Использование ключей RSA от AndroidKeyStore для установления соединения SSL - PullRequest
0 голосов
/ 04 октября 2019

Я сохраняю ключи 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)

...