我知道如何使用证书保护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连接一样)
答案 0 :(得分:5)
Java运行时环境在cacerts文件中附带了许多(使用最广泛的)证书颁发机构。如果您用于保护服务的证书由其中一个根CA签名,则您无需担心与客户端共享任何证书。
但是,如果您使用自签名证书,并且您不想在信任库中传递/导入证书,那么您可以实现自定义X509TrustManager并为您的连接创建自定义SSLContext。有关此blog。
的详细信息自签名证书对开发和测试环境很有用,但您确实应该考虑从Verisign,Thwate等公认的证书颁发机构签署服务器证书。
答案 1 :(得分:2)
如果我理解正确,那么您希望仅使用服务器端身份验证,就像连接到浏览器中的https站点一样,而无需客户端管理任何证书。
您的客户端将照常连接,只需在连接URL中替换https作为https即可。 Java以cacerts
的形式管理自己的一组“默认受信任的根CA权限”,$JRE HOME/lib/security
是位于{{1}}的JKS密钥库文件。如果您从任何CA的证书中购买证书,证书的颁发证书都来自cacerts中包含的证书之一,那么客户端的证书验证将自动成功。谷歌的“SSL / TLS服务器证书”,你会找到合适的供应商。
另一方面,如果您使用自行颁发的证书,则除了在客户端的证书信任库中导入自制证书之外,无法在客户端上成功进行证书验证。但这就是为什么“真正的”SSL / TLS证书需要花钱而你的自发证书却没有 - 任何人都可以生成自己的本土证书,但信任它们是完全不同的故事。
答案 2 :(得分:1)
您可以通过以下方式控制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将起作用。
在我的博客中,您可以看到客户端如何绕过服务器证书和主机名验证的示例(虽然不推荐,但对于测试很有用) http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over-ssl/
答案 3 :(得分:0)
只需与HTTPS建立连接即可。只要客户端使用标准的可信证书,它就可以正常工作。如果他们有自签名证书,您需要将证书导入java密钥库。
答案 4 :(得分:0)
浏览器中的HTTPS可以正常工作,因为客户端上有一个包含SSL证书的信任库。换句话说:客户端存储了证书。
如果你想要在客户端没有存储任何证书的HTTPS,我想你应该看看this article,它解释了如何关闭HTTPS连接上的默认证书验证。