这是接受自签名证书的有效方法吗?
我编写此代码是为了接受来自服务器的所有自签名证书:
private TrustManager[] createTrustManager() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (!chain[0].getIssuerDN().equals(chain[0].getSubjectDN())) {
throw new CertificateException("This is not a self-signed certificate");
}
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// leave blank to trust every client
}
}};
return trustAllCerts;
}
这是一种有效且充分的方法吗?
I wrote this code to accept all self-signed certificates from a server:
private TrustManager[] createTrustManager() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (!chain[0].getIssuerDN().equals(chain[0].getSubjectDN())) {
throw new CertificateException("This is not a self-signed certificate");
}
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// leave blank to trust every client
}
}};
return trustAllCerts;
}
Is this a valid and sufficient approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尽管它完成了它的工作,但您的方法基本上否定了正确的 PKI 的目的。如果您盲目信任任何自签名证书,那么使用 TLS 根本没有任何意义 - 任何人都可以创建可通过您的
TrustManager
的自签名证书。因此,如果您想要安全,那么您应该首先找出您的客户端应用程序将与哪些服务器通信,然后获取链接到这些服务的 TLS 服务器证书(在您的场景中,每个它们是自签名的,因此您无需关心中间证书)。
现在,使用这些证书,您创建一个 JKS“信任存储”文件并将证书放入其中 - 这是您要信任的证书集,未包含在此文件中的证书将被拒绝。要创建 JKS 文件,您可以使用 Java 的 keytool 命令,或者您可以使用
KeyStore
API 以编程方式执行此操作。最后,您将创建供
HttpClient
使用的SSLContext
,并使用如下创建的TrustManager
来init
它:其中
fin
是您的“信任存储”的InputStream
,pwd
是您用于加密它的密码。默认的TrustManager
实现让您只需要使用一组受信任的证书,其余的都会为您处理。Although it does its job, your approach basically denies the purpose of a proper PKI. If you blindly trust any self-signed certificate, then there is no point in using TLS at all - anyone can create a self-signed certificate that would pass your
TrustManager
.So, if you want to be secure, then you should first find out which servers your client application will be communicating with and then get the TLS server certificates that are linked to those services (in your scenario each of them is self-signed, so you don't need to care about intermediate certificates).
Now, using these certificates, you create a JKS "trust store" file and put the certificates in it - this is the set of certificates you are going to trust, certificates not contained in this file will be rejected. To create a JKS file you can either use Java's keytool command or you can do it programmatically using the
KeyStore
API.Finally you would create the
SSLContext
to be used by yourHttpClient
andinit
it with aTrustManager
created like this:where
fin
is theInputStream
of your "trust store" andpwd
the password you used to encrypt it. The defaultTrustManager
implementation this gives you needs only the set of trusted certificates to work with, the rest is taken care of for you.