添加trustStore以进行客户端身份validation

服务器和相应的客户端支持客户端身份validation,但如下所示: SSLHandshakeException:没有共同的密码套件 ,没有trustStore引用,即它们使用默认的trustStore。 如何指定trustStore?

ClassFileServer:

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); 

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

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

或通过命令行调用:

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

使用默认信任库不会导致“没有共同的密码套件”。 这是由于没有密钥库,或者没有密钥和证书,或者是在一个对等方或那个方面过度指定密码套件而导致没有协议。

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

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

请参阅JSSE参考指南 。