Android版本:
final SSLContext context = SSLContext.getInstance("TLS"); final KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(ctx.getAssets().open("ca_cli.pkcs12"), "password".toCharArray()); final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, "password".toCharArray()); context.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } @Override public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } } }, new SecureRandom());JVM版本:
final SSLContext context = SSLContext.getInstance("TLS"); final KeyStore keystore = KeyStore.getInstance("pkcs12"); keystore.load(new FileInputStream(new File("ca-cli.pkcs12")), "password".toCharArray()); final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, "password".toCharArray()); context.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } @Override public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } } }, new SecureRandom());代码非常相似,但JVM版本工作正常,Android版本产生:
09-16 12:24:17.024: E/AuthByPasswordLoader(14580): Got unexpected error 09-16 12:24:17.024: E/AuthByPasswordLoader(14580): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x656b0148: Failure in SSL library, usually a protocol error 09-16 12:24:17.024: E/AuthByPasswordLoader(14580): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1290 0x40086500:0x00000003)我试过转换PKCS12 - > BKS,但它没有帮助......
Android version:
final SSLContext context = SSLContext.getInstance("TLS"); final KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(ctx.getAssets().open("ca_cli.pkcs12"), "password".toCharArray()); final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, "password".toCharArray()); context.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } @Override public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } } }, new SecureRandom());JVM version:
final SSLContext context = SSLContext.getInstance("TLS"); final KeyStore keystore = KeyStore.getInstance("pkcs12"); keystore.load(new FileInputStream(new File("ca-cli.pkcs12")), "password".toCharArray()); final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, "password".toCharArray()); context.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } @Override public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { // TODO Auto-generated method stub } } }, new SecureRandom());The code is pretty same but JVM version works fine and Android version produces:
09-16 12:24:17.024: E/AuthByPasswordLoader(14580): Got unexpected error 09-16 12:24:17.024: E/AuthByPasswordLoader(14580): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x656b0148: Failure in SSL library, usually a protocol error 09-16 12:24:17.024: E/AuthByPasswordLoader(14580): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1290 0x40086500:0x00000003)I've tried to convert PKCS12 -> BKS but it doesn't helped...
最满意答案
因此,万一有人面临同样的问题 - 事实证明这是一个错误,这是在Android 3.0中引入的。
引用Kenny Root ( Android安全讨论主题 ):
谢谢,它看起来像Android 3.0中引入的错误。 它将要求客户端密钥类型具有相同的CA类型。 您看到这一点是因为您的客户端证书是RSA而CA是EC。
您可以通过包装KeyManager并拦截对chooseClientAlias的调用以将“RSA_EC”添加到keyTypes来解决此问题。
如果您对将来版本中的特定修补程序感兴趣: https : //android-review.googlesource.com/66581
So, in case someone face the same issue - it turned out that this is a bug, which was introduced in Android 3.0.
Quoting Kenny Root (Android Security Discussion thread):
Thanks, it looks like a bug that was introduced in Android 3.0. It will require that client key types have the same CA type. You are seeing this because your client certificate is RSA and the CA is EC.
You can work around this bug for your situation by wrapping the KeyManager and intercepting calls to chooseClientAlias to add "RSA_EC" to the keyTypes.
If you're interested in the particular fix that will be in a future release: https://android-review.googlesource.com/66581
更多推荐
发布评论