Я сохраняю ключи RSA client
и CA certificate
в AndroidKeyStore
для последующего извлечения и создания контекста SSL. Когда я пытаюсь установить соединение SSL, я получаю javax.net.ssl.SSLHandshakeException: Handshake failed
.
Если я использую PKCS12 KeyStore
вместо AndroidKeyStore
, то соединение SSL будет успешным. Но в PKCS12 repository
я не могу сохранить ключи, в отличие от AndroidKeyStore
, мне приходится загружать их при каждом подключении. Я подозреваю, что проблема в том, что в PKCS12
и AndroidKeyStore
ключи и сертификаты хранятся в разных форматах. Как я могу решить эту проблему?
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
if (!keyStore.containsAlias("Client")) {
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(mCertPKCS12, password.toCharArray());
keyStore.setEntry("Client", ks.getEntry("Client", null), null);
keyStore.setEntry("Server", ks.getEntry("Server", null), null);
}
KeyStore.PrivateKeyEntry keyClient = (KeyStore.PrivateKeyEntry) keyStore.getEntry("Client", null);
if (keyClient != null)
Log.d("###", "keyClient=" + keyClient.toString());
Certificate certClient = keyClient.getCertificate();
if (certClient != null)
Log.d("###", "certClient=" + certClient.toString());
final Certificate certServer = keyStore.getCertificate("Server");
if (certServer != null)
Log.d("###", "certServer=" + certServer.toString());
// Build a TrustManager, that trusts only the server certificate
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
for (int j = 0; j < chain.length; j++) {
chain[j].checkValidity();
try {
chain[j].verify(certServer.getPublicKey());
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) {
e.printStackTrace();
throw new CertificateException(e.getMessage());
}
}
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
String defaultAlg = KeyManagerFactory.getDefaultAlgorithm();
Log.d("aaa", "default cypher algorithm: " + defaultAlg);
// Build a KeyManager for Client auth
KeyManagerFactory kmf = KeyManagerFactory.getInstance(defaultAlg);
kmf.init(keyStore, null);
SSLContext sslc = SSLContext.getInstance("TLS");
sslc.init(kmf.getKeyManagers(), new TrustManager[]{tm}, null);
Причина: javax.net.ssl.SSLProtocolException: сбой рукопожатия SSL: ssl = 0x72c004a240: сбой в библиотеке SSL, обычно ошибка протокола 2019-10-04 11: 07: 23.042 21015-21174 / xxx.xxx.xxx W / System.err: ошибка: 10000418: подпрограммы SSL: OPENSSL_internal: TLSV1_ALERT_UNKNOWN_CA (внешний / boringssl / src / ssl / tls_record.cc: 579 0x72c001400000000000900-04 11: 07: 23.043 21015-21174 / xxx.xxx.xxx W / System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake (собственный метод) 2019-10-04 11: 07: 23.043 21015-21174 / xxx.xxx.xxx W / System.err: at com.android.org.conscrypt.SslWrapper.doHandshake (SslWrapper.java:374) 2019-10-04 11: 07: 23.043 21015-21174 / xxx.xxx. xxx W / System.err: at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake (ConscryptFileDescriptorSocket.java:217)