我将如何在两个 Java SE 应用程序之间建立套接字连接,其中密钥不是来自受信任的存储或证书,而是在应用程序本身中硬编码。
例如,客户端上的公钥和服务器上的私钥。在仍然使用标准TLS/SSL套接字API的同时,我将如何做到这一点?
您可以从证书和密钥文件生成JKS(Java Key Store)
,并将其导入 JRE 中。
您可以使用keytool
生成 JKS 并将其导入密钥库。
使用命令:keytool -import -alias <Your Alias> -file CertificateFile.cer -keystore <currentKeyStore>
默认情况下,您当前的密钥库应位于:JAVA_HOME-> JRE ->lib-> security-> cacerts
生成自签名证书,私钥进入服务器,带有公钥的证书进入客户端。之后,您需要在客户端正确设置SSLContext。这基本上可以通过3种方式实现。
1 - 将服务器证书 CA(用于自签名 CA == 证书(添加到客户端$JRE/lib/security/cacerts
文件中。这不是很好,因为在客户端上更新JRE后,您可能会丢失此更改。
2 - 将服务器证书放入密钥库并设置环境变量(使用 System.setProperty
或作为命令行选项-D
( javax.net.ssl.trustStore
、javax.net.ssl.trustStorePassword
和(可选(javax.net.ssl.trustStoreType
,请检查此答案以了解详细信息 https://stackoverflow.com/a/5871352/1516873
3 - 手动设置 SSLContext trustStoreManager,例如:
private final SSLContext createSSLContext()
throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream in = new FileInputStream("path to server certificate.pem"); // server certificate in PEM format
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(null);
try {
X509Certificate cacert = (X509Certificate) cf.generateCertificate(in);
trustStore.setCertificateEntry("server_alias", cacert);
} finally {
IOUtils.closeQuietly(in);
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("SSL"); // TLS e.g.
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}