【发布时间】:2014-06-04 04:19:11
【问题描述】:
我想通过 SSL 连接到我的服务器。因此,我使用以下命令在服务器上生成了证书:
openssl genrsa -out server.pem 2048
openssl req -new -x509 -nodes -sha1 -days 3650 -key server.pem > server.cert
如果我使用这样的 TrustManager 信任客户端上的所有证书,则连接有效:
X509TrustManager tm = new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(
X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(
X509Certificate[] certs, String authType) {
}
};
但我当然不想信任所有证书,而只信任我的证书。我尝试了几个命令来导入证书,例如:
keytool -import -alias ca -file server.cert -keystore cacerts
但我总是得到这个错误:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我需要做什么才能让它工作?有人可以为不太熟悉 cryto 领域的人解释必要的步骤吗?
编辑: 正如 Donal Fellows 所提议的,我尝试了使用自定义 X509TrustManager 的方法并且它有效。但它也像那样安全吗?如果我只是在“getAcceptedIssuers”方法中返回“null”,它也能正常工作,我不太清楚为什么:
X509TrustManager tm = new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
X509Certificate[] trustedCerts = new X509Certificate[1];
try{
InputStream inStream = new FileInputStream("server.cert");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
inStream.close();
trustedCerts[0] = cert;
}catch(Exception e){
e.printStackTrace();
}
return trustedCerts;
}
@Override
public void checkClientTrusted(
X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
boolean match = false;
try{
InputStream inStream = new FileInputStream("server.cert");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
inStream.close();
for(X509Certificate c : chain){
if(c.equals(cert)){
match = true;
}
}
}catch(Exception e){
throw new CertificateException();
}
if(!match)
throw new CertificateException();
}
};
【问题讨论】:
标签: java security ssl certificate truststore