我需要模拟客户端api请求以进行测试。我们的服务器现在使用https,建议我使用OkHttpClient而不是原始的BaseHttpClient实现。我发现我需要将.sslSocketFactory(sslSocketFactory, x509TrustManager)
添加到客户端构建器中,并且还找到了加载证书的有用代码:
private X509TrustManager trustManagerForCertificates(InputStream in)
{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
char[] password = "password".toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
return (X509TrustManager) trustManagers[0];
}
我的问题是我的证书具有密钥,我找不到一种将.crt
和.key
文件的内容成对提供的方法。如果我要卷曲它,我可以做
curl --tlsv1.2 --insecure -v --key ./client.key --cert ./client.crt https://myserver/api/request
是否可以使用OkHttp做类似的事情?还是我必须使用现有的证书及其密钥来生成新证书?
答案 0 :(得分:0)
最后,我设法使用this site的库中的BouncyCastle中的代码来使其工作。
要使其正常工作,我还需要ca.crt
(示例中已包含它-感谢--insecure
开关,curl命令可以做到这一点)。我经过的许多站点都让我认为我需要使用ca
和client
证书创建证书链,但是从链接代码中可以看到,解决方案是有两个密钥存储:一个用于CA,用于TrustManager
,一个用于客户证书,用于KeyManager
。然后可以用这两个来初始化SSLContext
。
我遇到的最后一个障碍是一个例外:
java.lang.ClassNotFoundException: org.bouncycastle.jcajce.JcaJceHelper
这是由于从各种来源导入了多个版本的bouncycastle
。确保使用正确的bcprov
和bcpkix
版本解决了此问题。