5

服务器和各自的客户端支持客户端身份验证,但如下所述:SSLHandshakeException: no cipher suites in common,没有 trustStore 引用,即它们使用默认的 trustStore。如何指定 trustStore?

类文件服务器:

private static ServerSocketFactory getServerSocketFactory(String type) {
    if (type.equals("TLS")) {
        SSLServerSocketFactory ssf = null;

        Properties systemProps = System.getProperties();
        systemProps.put( "javax.net.ssl.trustStore", "cacerts.jks");
        systemProps.put( "javax.net.ssl.trustStorePassword", "p@ssw0rd");
        System.setProperties(systemProps);

        try {
            // set up key manager to do server authentication
            SSLContext ctx;
            KeyManagerFactory kmf;
            KeyStore ks;
            char[] passphrase = "p@ssw0rd".toCharArray();

            ctx = SSLContext.getInstance("TLS");
            kmf = KeyManagerFactory.getInstance("SunX509");
            ks = KeyStore.getInstance("JKS");
            ks.load(new FileInputStream("keystore.jks"), passphrase);
            kmf.init(ks, passphrase);
            ctx.init(kmf.getKeyManagers(), null, null);

            ssf = ctx.getServerSocketFactory();
            return ssf;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

SSLSocketClientWithClientAuth:

    try {

        /*
         * Set up a key manager for client authentication
         * if asked by the server.  Use the implementation's
         * default TrustStore and secureRandom routines.
         */
        Properties systemProps = System.getProperties();
        systemProps.put( "javax.net.ssl.trustStore", "cacerts.jks");
        systemProps.put( "javax.net.ssl.trustStorePassword", "changeit");
        System.setProperties(systemProps);

        SSLSocketFactory factory = null;
        try {
            SSLContext ctx;
            KeyManagerFactory kmf;
            KeyStore ks;
            char[] passphrase = "changeit".toCharArray();

            ctx = SSLContext.getInstance("TLS");
            kmf = KeyManagerFactory.getInstance("SunX509");
            ks = KeyStore.getInstance("JKS");

            ks.load(new FileInputStream("keystore.jks"), passphrase);

            kmf.init(ks, passphrase);
            ctx.init(kmf.getKeyManagers(), null, null);

            factory = ctx.getSocketFactory();
        } catch (Exception e) {
            throw new IOException(e.getMessage());
        }

        SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
4

2 回答 2

3

trustStore通过设置系统属性来指定:

System.setProperty("javax.net.ssl.trustStore", "cacerts.jks");

或通过命令行调用:

-Djavax.net.ssl.keyStore=path/to/keystore.jks

于 2012-04-04T12:59:58.620 回答
1

“没有共同的密码套件”不是由使用默认信任库引起的。这是由于没有密钥库,或者其中没有私钥和证书,或者是由于在一个对等方或另一个对等方过度指定密码套件而导致无法达成协议。

如果服务器没有私钥,它就不能使用除了不安全的匿名密码套件之外的任何密码套件,默认情况下禁用这些密码套件,并且应该保持这种状态。因此发出警报。

当且仅当您使用自签名证书时,使用默认信任库会导致不同的问题。简单的解决方案:不要。更复杂的解决方案:从各自的密钥库中导出各自的证书,然后将它们导入对方的信任库。

请参阅JSSE 参考指南

于 2012-03-04T08:46:51.853 回答