简体   繁体   English

具有自签名证书的Java SSL连接,无需将完整的密钥库复制到客户端

[英]Java SSL connection with self-signed certificate without copying complete keystore to client

I am setting up a licensing servlet in Java together with a client app that will post request for new licenses and validate existing licenses at that server. 我正在使用Java与客户端应用程序一起设置许可servlet,该客户端应用程序将发布对新许可的请求并在该服务器上验证现有许可。 The servlet runs in Tomcat. 该servlet在Tomcat中运行。 I've configured Tomcat so that it only allows connections to the servlet over https, and this works just fine. 我已经配置了Tomcat,以便它仅允许通过https连接到servlet,这很好用。

I have created a self-signed certificate using 'keytool -genkey -alias www.mysite.com -keyalg RSA -keystore license.store' which creates a file license.store and pointed tomcat to this keystoreFile with its password asdf1234 . 我已经使用'keytool -genkey -alias www.mysite.com -keyalg RSA -keystore license.store'创建了一个自签名证书,该证书创建了一个文件license.store并指向asdf1234指向此keystoreFile,其密码为asdf1234

When I just try to connect from the client to the servlet over https in Java, I receive the familiar PKIX path building failed because the certificate is not in the truststore. 当我尝试通过Java中的https从客户端连接到servlet时,由于证书不在信任库中,我收到了熟悉的PKIX path building failed I tried to fixed this using this suggestion resulting in the code below: 我尝试使用建议来解决此问题,导致以下代码:

private SSLSocketFactory getSSLFactory() throws Exception {

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    InputStream is = this.getClass().getResourceAsStream("license.store");

    if(is ==null) {
        return null;
    }

    keyStore.load(is, "asdf1234".toCharArray());
    is.close();

    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);

    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(null, tmf.getTrustManagers(), null);

    return ctx.getSocketFactory();
}

After which I call: 之后,我打电话给:

HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setSSLSocketFactory(getSSLFactory());

which results in a succesfull connection. 这将导致成功的连接。

Now the problem is that I only get this to work when I copy the license.store to the client and load that into the KeyStore.load() . 现在的问题是,只有将license.store复制到客户端并将其加载到KeyStore.load()时,我才能license.store工作。 It doesn't strike me as very safe to copy the private key and its password that the server uses to the client. 将服务器使用的私钥及其密码复制到客户端并不十分安全。 Is there any way to extract only the public key from the license.store and use that? 有什么方法可以从license.store中仅提取公钥并使用它? I've been searching this forum and others for a day now and just can't seem to get it. 我已经在这个论坛和其他论坛上搜索了一天,但似乎无法获取。

You shouldn't be generating a public-private key pair, but rather import the certificate of the server into your (the client's) Java truststore. 您不应该生成一个公钥-私钥对,而是将服务器的证书导入到您(客户端)的Java信任库中。 The certificate is not a secret, and thus does not provide a security risk on the client side. 该证书不是机密信息,因此不会在客户端提供安全风险。 See the -import option for keytool. 请参阅-import选项以获取keytool。 Here's in an example . 这是一个例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM