【发布时间】:2016-10-09 14:41:31
【问题描述】:
我想在安卓设备上安装一个 SSL 加密的 TCP 服务器,在电脑上安装一个客户端来连接设备。
我使用自己的密钥库在 Android 设备上创建 SSLServerSocket。
final KeyStore localTrustStore = KeyStore.getInstance("BKS"); //NON-NLS
final InputStream in = context.getResources().openRawResource(R.raw.syncapp);
localTrustStore.load(in, "secret".toCharArray()); //Keystore pw
in.close();
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); //NON-NLS
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(localTrustStore);
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(localTrustStore, "secret".toCharArray()); //privat key pw
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
serverSocket = sslContext.getServerSocketFactory().createServerSocket(SERVER_PORT);
((SSLServerSocket) serverSocket).setNeedClientAuth(true);
然后我等待客户端连接。当客户端想要连接一个新线程并且请求流时:
final DataInputStream input = new DataInputStream(this.clientSocket.getInputStream());
final DataOutputStream output = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
首先,我将此代码与 USB-Tethering 一起使用,以在计算机和 android 设备之间建立连接。所以没有启用 Wifi/网络。一切都很完美。
然后我激活了 android 设备上的 wifi 并连接到没有互联网的 wlan。 但是现在调用 getInputStream() 似乎需要 5 到 10 秒。 如果我停用 SSL,它会完美运行。 如果 wlan 确实连接到互联网,则也没有延迟。 我用 Android 4.2 和 5.1 对此进行了测试。 更新:现在我可以用 Android 6 测试这个问题。问题似乎已经解决了......
握手已正确完成,但之后 Android 设备上似乎存在某种延迟。 (对 getInputStream 的调用会消耗该时间) 一些开发人员说它将执行 DNS 反向查找,这将遇到超时。
看一下捕获,第一次连接是在禁用 wifi 时建立的。进行数据传输需要 0.3 秒。然后我刚刚激活了wifi,我没有通过wifi连接,它仍然通过usb通信。并且耗时超过 5 秒。
我也在这里发现了问题,但他们使用的是客户端套接字。我需要一个服务器套接字。有谁知道如何解决这个问题?
【问题讨论】:
-
使用同一个文件作为密钥库和信任库没有任何意义。
-
你能详细说明一下吗?我有一个用于服务器的密钥库,其中包含一个密钥对和来自客户端的公钥。客户端有他自己的密钥对和来自服务器的公钥。所以他们可以相互验证,但没有其他人可以连接。
-
信任库是您信任的人。这可能是由委员会决定的事情,可能是站点范围或公司范围,或者默认情况下实际上是 JDK 范围。密钥库包含您自己的私钥和签名证书。这些是秘密。他们周围的安全制度在每种情况下都完全不同。对两者使用相同的物理文件没有任何意义。
-
您是否已将证书添加到您的客户端?即,由于您可能将密钥库与您创建的证书一起使用,除非您将其添加到其受信任的证书列表中,否则客户端将不知道它。