【发布时间】:2015-08-11 10:19:25
【问题描述】:
我正在尝试与远程服务器建立安全通信,不幸的是,该服务器是自签名的。 我在这里阅读了官方的 android 文档:https://developer.android.com/training/articles/security-ssl.html 并写在这里,当证书颁发机构不在 android 列表中时,您需要自己接受服务器证书。所以我这样做了:
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream mInputStream = new ByteArrayInputStream(mCertificateBytes);
Certificate certificate = cf.generateCertificate(mInputStream);
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", certificate);
TrustManager[] customTrustManager = {new CustomTrustManager2(keyStore)};
kmf.init(keyStore, null);
KeyManager[] keyManagers = kmf.getKeyManagers();
sslContext.init(keyManagers, customTrustManager, null);
我的 CustomTrustManager2.java 就像:
public class CustomTrustManager2 implements X509TrustManager {
private final X509TrustManager originalX509TrustManager;
private final KeyStore trustStore;
public CustomTrustManager2(KeyStore trustStore) throws NoSuchAlgorithmException,
KeyStoreException {
this.trustStore = trustStore;
TrustManagerFactory originalTrustManagerFactory = TrustManagerFactory.getInstance("X509");
originalTrustManagerFactory.init(this.trustStore);
TrustManager[] originalTrustManagers = originalTrustManagerFactory.getTrustManagers();
originalX509TrustManager = (X509TrustManager) originalTrustManagers[0];
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
try {
originalX509TrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException originalException) {
originalException.printStackTrace();
try {
X509Certificate[] reorderedChain = reorderCertificateChain(chain);
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
CertificateFactory factory = CertificateFactory.getInstance("X509");
CertPath certPath = factory.generateCertPath(Arrays.asList(reorderedChain));
PKIXParameters params = new PKIXParameters(trustStore);
params.setRevocationEnabled(false);
validator.validate(certPath, params);
} catch (Exception ex) {
ex.printStackTrace();
throw originalException;
}
}
}
但它不工作,我收到错误:
java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
W/System.err? at om.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:318)
W/System.err? at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:209)
W/System.err? at com.test.sample.utils.http.CustomTrustManager2.checkServerTrusted(CustomTrustManager2.java:78)
W/System.err? at com.google.android.gms.org.conscrypt.Platform.checkServerTrusted(SourceFile:164)
W/System.err? at android.os.Looper.loop(Looper.java:145)
W/System.err? at android.os.HandlerThread.run(HandlerThread.java:61)
W/System.err? Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
W/System.err? ... 31 more
I/System.out? First error end
I/System.out? second error start
W/System.err? java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.
W/System.err? at com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:122)
W/System.err? at com.sec.android.security.pkix.SecCertPathValidatorSpi.engineValidate(SecCertPathValidatorSpi.java:100)
W/System.err? at java.security.cert.CertPathValidator.validate(CertPathValidator.java:191)
W/System.err? at com.test.sample.utils.http.CustomTrustManager2.checkServerTrusted(CustomTrustManager2.java:90)
W/System.err? at com.google.android.gms.org.conscrypt.Platform.checkServerTrusted(SourceFile:164)
W/System.err? at com.google
W/System.err? at android.os.HandlerThread.run(HandlerThread.java:61)
W/System.err? Caused by: com.android.org.bouncycastle.jce.provider.AnnotatedException: TrustAnchor found but certificate validation failed.
W/System.err? at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.findTrustAnchor(CertPathValidatorUtilities.java:237)
W/System.err? at com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:117)
W/System.err? ... 31 more
W/System.err? Caused by: java.security.SignatureException
W/System.err? at com.google.android.gms.org.conscrypt.OpenSSLX509Certificate.verifyOpenSSL(SourceFile:353)
W/System.err? at com.google.android.gms.org.conscrypt.OpenSSLX509Certificate.verify(SourceFile:384)
W/System.err? at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.verifyX509Certificate(CertPathValidatorUtilities.java:1431)
W/System.err? at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.findTrustAnchor(CertPathValidatorUtilities.java:224)
W/System.err? ... 32 more
【问题讨论】:
-
所以服务器证书不仅是自签名的而且是无效的。向服务器管理员投诉。