我当前正在尝试创建一个简单的Java服务器,该服务器使用SSLServerSocket来加密流量。我也在用Android编写客户端。经过大量搜索,您得出的结论是我必须为Android应用程序创建一个密钥库,一个证书和一个密钥库。我使用了以下命令:
1。服务器的密钥库
keytool -genkey -v -alias serverKey -keyalg RSA -keystore ./server.ks -storetype JKS -storepass password -keypass password
2。 Android应用程序的密钥库
keytool -genkey -alias androidKey -keyalg RSA -keystore ./client.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /path/to/jar/bcprov-jdk16-1.53.jar -storepass pw -keypass pw
3。从服务器导出证书
keytool -export -alias serverKey -keystore ./server.ks -file serverKey.cer -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /path/to/jar/bcprov-jdk16-1.53.jar
4。将证书导入到Android密钥库中
keytool -import -alias serverKey -file serverKey.cer -keystore ./client.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /path/to/jar/bcprov-jdk16-1.53.jar
然后我将Android密钥库文件粘贴到我的Android项目中,并使用以下代码打开安全连接:
private SSLSocketClient(String ip,int port) {
try {
KeyStore store = KeyStore.getInstance("BKS");
store.load(getResources().openRawResource(R.raw.client),"pw".toCharArray());
KeyManagerFactory keyManager = KeyManagerFactory.getInstance("X509");
keyManager.init(store,"pw".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
tmf.init(store);
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManager.getKeyManagers(),tmf.getTrustManagers(),new SecureRandom());
SSLSocket socket = (SSLSocket) context.getsocketFactory().createSocket(ip,port);
// Continue using this socket like any other socket,e.g.:
// DataOutputStream os = new DataOutputStream(socket.getOutputStream());
// os.writeUTF("Hello server!");
} catch (Exception ex) {
ex.printStackTrace();
}
}
服务器端如下所示:(我将server.ks和serverKey.cer文件粘贴到了相应的目录中。)
private void initialize() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream("path/to/server.ks"),"pw".toCharArray());
keyManagerFactory.init(keyStore,"pw".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(),new SecureRandom());
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(this.port);
System.out.println("Server ready. Waiting for a client to connect...");
SSLSocket socket = (SSLSocket) sslServerSocket.accept();
// Continue to use the SSLServerSocket like any other ServerSocket
} catch (NoSuchAlgorithmException | KeyStoreException | CertificateException |
IOException | UnrecoverableKeyException | KeyManagementException ex) {
ex.printStackTrace();
}
}
当我尝试从Android客户端连接到服务器时,一切正常。但是我只是不相信自己做得对。我以前从未使用过SSL,因此对此进行了大量的搜索。我的问题仅仅是,如果我做的一切正确,还是弄乱了什么。我还查看了从我的客户端到Wireshark到服务器的流量,以尝试确认它以正确的方式使用SSL(据我所知)。就像我说的那样,我不确定是否一切正确。我不想打开“后门”,只是因为我忘记了一些东西。
此外,是否可以仅允许某些设备连接到服务器?例如仅我的Android客户端。我认为这就是TrustStore的目的,但是我到底将如何完成/使用它?