我正在尝试与远程服务器建立安全通信,不幸的是,这是自签名的。 我在这里阅读官方的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
答案 0 :(得分:-2)
我认为只要是自签名证书就会有问题,他们无法获得第三方签署的有效证书?因为当两个设备之间存在防火墙时,自签名证书总是会给您带来问题。