edw*_*win 2 authentication ssl android bouncycastle
以下测试设置在Android模拟器上运行正常.它使用相互身份验证打开与外部服务器的基于SSL/TLS的连接:
ca.crt(验证服务器证书):
----- BEGIN CERTIFICATE -----
BASE64编码 -
-----结束证书-----
client.p12(包括由服务器信任的私有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);
}
Run Code Online (Sandbox Code Playgroud)
但是,client.p12在运行时不可用.http客户端通过单独的专用通道接收以下配置:
因此,我将以客户端.p12作为输入更改了密钥库初始化,如下所示:
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);
Run Code Online (Sandbox Code Playgroud)
运行时执行时抛出异常
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)
Run Code Online (Sandbox Code Playgroud)
总结:一切都在使用pcks12证书/私钥对,但没有使用上述格式的两个.
根据之前提到的client.der/client.pem,有什么建议是出错或建议实现客户端身份验证吗?
PS运行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...
//
}
Run Code Online (Sandbox Code Playgroud)
您可以尝试使用该void setKeyEntry(String alias, Key key, char[] password, Certificate[] chain)方法注册密钥和证书,似乎支持(未经测试).
| 归档时间: |
|
| 查看次数: |
4410 次 |
| 最近记录: |