java 如何通过 Web 服务制作“简单 SSL”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6810634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make 'simple SSL' thru Web Services?
提问by razor
I know how to secure Web Services using certificates. that's my client code:
我知道如何使用证书保护 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);
Now, how to make 'simple SSL' ? How to make SSL connection without storing certificate on the client side. (Like connecting thru HTTPS in browser)
现在,如何制作“简单 SSL”?如何在客户端不存储证书的情况下进行 SSL 连接。(就像在浏览器中通过 HTTPS 连接一样)
采纳答案by helios
Java Runtime Environment does come with a lots (most widely used) Certificate Authorities in cacerts file. If the certificate you used to secure your service is signed by one of those root CAs, then you need not worry about sharing any certificate with clients.
Java 运行时环境确实在 cacerts 文件中提供了许多(最广泛使用的)证书颁发机构。如果您用来保护服务的证书是由这些根 CA 之一签署的,那么您无需担心与客户端共享任何证书。
However if you used self-signed certificate, and you don't want to pass/import certificate in truststore then you can implement custom X509TrustManager and create custom SSLContext for your connections. More details in this blog.
但是,如果您使用自签名证书,并且不想在信任库中传递/导入证书,那么您可以实现自定义 X509TrustManager 并为您的连接创建自定义 SSLContext。在这个博客中有更多细节。
Self-signed certificate are useful for development and test environments but you really should consider getting your server certificate signed from a recognized Certificate Authority like Verisign, Thwate etc.
自签名证书对于开发和测试环境很有用,但您确实应该考虑从公认的证书颁发机构(如 Verisign、Thwate 等)获得服务器证书的签名。
回答by emboss
If I understand you correctly, then you want to have only server-side authentication much in the same way as if you connected to an https site in your browser, without requiring your clients to manage any certificates.
如果我理解正确,那么您只希望进行服务器端身份验证,就像您在浏览器中连接到 https 站点一样,而无需您的客户端管理任何证书。
Your clients would connect as usual, simply replacing an http for an https in the connection URL. Java manages its own set of "default trusted root CA authorities" in the form of cacerts
, a JKS keystore file located in $JRE HOME/lib/security
. If you buy a certificate from any CA whose issuing certificate roots in one of the certificates contained in cacerts, then the client's certificate validation will automagically succeed. Google for "SSL/TLS server certificate" and you will find suitable vendors.
您的客户端会像往常一样连接,只需将连接 URL 中的 http 替换为 https。Javacacerts
以 .JKS 密钥库文件的形式管理自己的一组“默认受信任的根 CA 权限”,该文件位于$JRE HOME/lib/security
. 如果您从任何 CA 购买证书,该证书的颁发证书源于 cacerts 中包含的其中一个证书,那么客户端的证书验证将自动成功。谷歌搜索“SSL/TLS 服务器证书”,你会找到合适的供应商。
If you would use a self-issued certificate on the other hand, then there's no way to make certificate validation succeed on the client other than importing your self-made certificate in the client's certificate trust store. But that's why a "real" SSL/TLS certificate costs money and your self-issued certificate doesn't - anyone can generate their home-grown certificates, but trusting them is an entirely different story.
另一方面,如果您将使用自行颁发的证书,那么除了在客户端的证书信任库中导入您的自制证书之外,没有其他方法可以使客户端上的证书验证成功。但这就是为什么“真正的”SSL/TLS 证书要花钱而您自己颁发的证书不需要的原因——任何人都可以生成自己的证书,但信任它们是完全不同的故事。
回答by Jakub
You can control if the https server requires client certificates in this way:
您可以通过这种方式控制 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);
If client certs are not required, clients can connect without client certificate, so simple calling https will work.
如果不需要客户端证书,客户端可以在没有客户端证书的情况下进行连接,因此简单调用 https 就可以了。
In my blog you can see example of client for how to bypass the server certificate and hostname validation (although not recommended, useful e.g. for testing) http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over-ssl/
在我的博客中,您可以看到有关如何绕过服务器证书和主机名验证的客户端示例(虽然不推荐,但对于测试很有用) http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over -SSL/
回答by boes
HTTPS in browsers works because there is a truststore containing SSL certificates on the client. In other words: There are certificates stored on the client side.
浏览器中的 HTTPS 有效,因为客户端上有一个包含 SSL 证书的信任库。换句话说:有证书存储在客户端。
If you want HTTPS without any certificate stored on the client side, I think you should have a look at this article, which explains how to turn off the default certificate validation on HTTPS connection.
如果你想在客户端不存储任何证书的HTTPS,我认为你应该看看这篇文章,它解释了如何关闭HTTPS连接上的默认证书验证。
回答by ryber
Just make the connection with HTTPS. As long as the client is using standard trusted certs it will work just fine. If they have a self signed cert you will need to to import the cert into the java keystore.
只需使用 HTTPS 建立连接即可。只要客户端使用标准的可信证书,它就可以正常工作。如果他们有自签名证书,您需要将证书导入 java 密钥库。