如何通过Web服务制作“简单SSL”?

我知道如何使用证书保护Web服务。 那是我的客户代码:

SSLContext ssl = SSLContext.getInstance("SSLv3"); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); String password = Configuration.getConfig("keyStorePassword"); store.load(new FileInputStream(new File(Configuration.getConfig("keyStore"))), password.toCharArray()); kmf.init(store, password.toCharArray()); KeyManager[] keyManagers = new KeyManager[1]; keyManagers = kmf.getKeyManagers(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(store); TrustManager[] trustManagers = tmf.getTrustManagers(); ssl.init(keyManagers, trustManagers, new SecureRandom()); HttpsConfigurator configurator = new HttpsConfigurator(ssl); Integer port = Integer.parseInt(Configuration.getConfig("port")); HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(Configuration.getConfig("host"), port), 0); httpsServer.setHttpsConfigurator(configurator); Implementor implementor = new Implementor(); // class with @WebService etc. HttpContext context = (HttpContext) httpsServer.createContext("/EventWebService"); Endpoint endpoint = Endpoint.create( implementor ); endpoint.publish(context); 

现在,如何制作“简单的SSL”? 如何在不在客户端存储证书的情况下建立SSL连接。 (就像在浏览器中通过HTTPS连接一样)

Java运行时环境在cacerts文件中附带了许多(最广泛使用的)证书颁发机构。 如果您用于保护服务的证书由其中一个根CA签名,则您无需担心与客户端共享任何证书。

但是,如果您使用自签名证书,并且您不想在信任库中传递/导入证书,则可以实现自定义X509TrustManager并为您的连接创建自定义SSLContext。 此博客中的更多详细信息。

自签名证书对开发和测试环境很有用,但您确实应该考虑从Verisign,Thwate等公认的证书颁发机构签署服务器证书。

如果我理解正确,那么您希望仅使用服务器端身份validation,就像连接到浏览器中的https站点一样,而无需客户端管理任何证书。

您的客户端将照常连接,只需在连接URL中替换http为https。 Java以cacerts的forms管理自己的一组“默认受信任的根CA权限”,这是一个位于$JRE HOME/lib/security的JKS密钥库文件。 如果您从任何CA的证书中获取证书,证书的颁发证书都来自cacerts中包含的证书之一,那么客户端的证书validation将自动成功。 谷歌的“SSL / TLS服务器证书”,你会找到合适的供应商。

另一方面,如果您使用自行颁发的证书,则除了在客户端的证书信任库中导入自制证书之外,无法在客户端上成功进行证书validation。 但这就是为什么“真正的”SSL / TLS证书需要花钱而你的自发证书却没有 – 任何人都可以生成自己的本土证书,但信任它们是完全不同的故事。

您可以通过以下方式控制https服务器是否需要客户端证书:

 HttpsConfigurator cfg = new HttpsConfigurator(sslCtx){ public void configure(HttpsParameters params) { SSLParameters sslparams = getSSLContext().getDefaultSSLParameters(); // Modify the default params: // Using this, server will require client certs //sslparams.setNeedClientAuth(true); // Using this, server will request client certs. But if not available, // it will continue anyway. sslparams.setWantClientAuth(true); params.setSSLParameters(sslparams); } }; HttpsServer httpsS = HttpsServer.create(new InetSocketAddress(8081), 50); httpsS.setHttpsConfigurator(cfg); 

如果不需要客户端证书,客户端可以在没有客户端证书的情况下连接,因此简单的呼叫https将起作用。

在我的博客中,您可以看到客户端的示例,了解如何绕过服务器证书和主机名validation(虽然不推荐,有用,例如用于测试) http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over -ssl /

只需与HTTPS建立连接即可。 只要客户端使用标准的可信证书,它就可以正常工作。 如果他们有自签名证书,您需要将证书导入java密钥库。

浏览器中的HTTPS可以工作,因为客户端上有一个包含SSL证书的信任库。 换句话说:客户端存储了证书。

如果你想要在客户端没有存储任何证书的HTTPS,我想你应该看看这篇文章 ,它解释了如何关闭HTTPS连接上的默认证书validation。