gpt4 book ai didi

android - Android 上带客户端身份验证的 SSL/TLS http 客户端的运行时配置

转载 作者:搜寻专家 更新时间:2023-11-01 07:38:31 24 4
gpt4 key购买 nike

以下测试设置在 Android 模拟器上运行良好。它打开一个基于 SSL/TLS 的连接到一个使用相互认证的外部服务器:

ca.crt(验证服务器证书):
-----开始证书-----
BASE64 编码的东西
-----证书结束-----

client.p12(包括由服务器信任的私有(private)CA签名的客户端证书):PKCS#12格式

运行成功的Java/Android代码:

trustStore = KeyStore.getInstance("bks");
trustStore.load(null, null);
caCertificate = getX509Certificate("/some/path/ca.crt");
trustStore.setCertificateEntry("ca-cert", caCertificate);

keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(null, null);
InputStream is = new FileInputStream("/some/path/client.p12");
keyStore.load(is, "passwd".toCharArray());

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
trustManagerFactory.init(trustStore);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
keyManagerFactory.init(keyStore, null);

context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());

URL url = new URL("https://www.backend.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(context.getSocketFactory());
connection.setDoInput(true);
connection.setDoInput(true);
BufferedReader urlReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
while ( (inputLine=urlReader.readLine()) != null ){
System.out.println(inputLine);
}

但是,client.p12 在运行时不可用。 http 客户端通过一个单独的专属 channel :

  • PEM 编码的 X509 客户端证书 (client.crt)
  • DER格式私钥客户端(client.der)

因此,我将上面以 client.p12 作为输入的 keystore 初始化更改为以下内容:

keyStore = KeyStore.getInstance("bks");
keyStore.load(null, null);
clientCertificate = getX509Certificate("/some/path/client.crt");
byte[] privateKey = getBytesFromFile("/some/path/client.der");
Certificate[] chain = new Certificate[2];
chain[1] = caCertificate;
chain[0] = clientCertificate;
keyStore.setCertificateEntry("client-cert", clientCertificate);
keyStore.setKeyEntry("client-cert-key", privateKey, chain);

运行时执行时抛出异常

context = SSLContext.getInstance("TLS");
----> context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());

java.lang.RuntimeException: forget something!
at org.bouncycastle.jce.provider.JDKKeyStore$StoreEntry.getObject(JDKKeyStore.java:314)
at org.bouncycastle.jce.provider.JDKKeyStore.engineGetKey(JDKKeyStore.java:604)
at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:376)
at java.security.KeyStore.getEntry(KeyStore.java:734)
at org.apache.harmony.xnet.provider.jsse.KeyManagerImpl.<init>(KeyManagerImpl.java:72)

总结:使用 pcks12 证书/私钥对一切正常,但没有以上述格式使用两者。

有什么问题的建议,或者对前面提到的 client.der/client.pem 实现客户端身份验证的建议?

附言运行 keytool 运行时不是一个选项,因为我在运行时没有它,我不想那样做。

最佳答案

简单:未实现将键作为字节数组传递。引用自 JDKKeyStore.java:

        else
{
throw new RuntimeException("forget something!");
// TODO
// if we get to here key was saved as byte data, which
// according to the docs means it must be a private key
// in EncryptedPrivateKeyInfo (PKCS8 format), later...
//
}

您可以尝试使用 void setKeyEntry(String alias, Key key, char[] password, Certificate[] chain) 方法注册您的 key 和证书,似乎支持(未测试) .

关于android - Android 上带客户端身份验证的 SSL/TLS http 客户端的运行时配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7245007/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com