这是接受自签名证书的有效方法吗? [英] Is this a valid approach to accept self-signed certificates?
问题描述
我写了此代码接受来自服务器的所有自签名证书:
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 .getSubjectDN())){
throw new CertificateException(This is not a self-signed certificate);
}
}
public void checkClientTrusted(X509Certificate [] chain,String authType)throws CertificateException {
//留空以信任每个客户
}
}}
return trustAllCerts;
}
这是一个有效且充分的方法吗?
虽然它完成了它的工作,你的方法基本上否认了一个正确的PKI的目的。如果您盲目信任任何自签名证书,那么根本没有必要使用TLS - 任何人都可以创建一个自签名证书,通过您的 TrustManager
。
所以,如果你想要 secure ,那么你应该首先找出你的客户端应用程序将要与之通信的服务器,然后获取TLS服务器链接到这些服务的证书(在您的场景中,每个都是自签名的,因此您不需要关心中间证书)。
现在,使用这些证书,您创建一个JKS信任存储文件并将证书放入其中 - 这是您要信任的证书集,此文件中不包含的证书将被拒绝。要创建JKS文件,您可以使用Java的 keytool 命令,或者您可以使用 KeyStore
API以编程方式进行。
最后,您将创建 HttpClient $ c>使用的
SSLContext
$ c>和 init
它与 TrustManager
创建如下:
KeyStore ks = KeyStore.getInstance(JKS);
ks.load(fin,pwd);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(PKIX);
tmf.init(ks);
其中 fin
是 InputStream
您的信任存储和 pwd
您用于加密它的密码。默认的 TrustManager
实现这给你只需要一组可信的证书来处理,剩下的就是照顾你。
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?
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 your HttpClient
and init
it with a TrustManager
created like this:
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fin, pwd);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(ks);
where fin
is the InputStream
of your "trust store" and pwd
the password you used to encrypt it. The default TrustManager
implementation this gives you needs only the set of trusted certificates to work with, the rest is taken care of for you.
这篇关于这是接受自签名证书的有效方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!