此问题可能与How can I pin a certificate with Square OKHTTP?重复。但由于我不清楚,我再次提问。我必须将SSL证书附加到我的http客户端。我使用的是改装版2.2.0
和okHttp版本3.6.0
我有.crt
格式的证书。目前,我正在执行固定as shown here的证书。但我不知道它的适当与否。
以下是我的代码
static void pinCertificate(Context context, OkHttpClient.Builder builder) {
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream cert = context.getResources().openRawResource(R.raw.certificate);
Certificate ca;
ca = cf.generateCertificate(cert);
// creating a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
builder.sslSocketFactory(sslContext.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
使用okHttp固定.crt
证书是否正确?我们如何测试它是否正确地进行了握手?
如果错误,任何人都可以显示示例代码来正确固定证书吗?
我看到了一些像https://medium.com/@develodroid/android-ssl-pinning-using-okhttp-ca1239065616
但它与我实施的完全不同。他们没有使用crt
文件。
如果有人可以分享关于证书固定的更好解释以及如何在okHttp中完成,那将非常有帮助。 提前致谢!!
答案 0 :(得分:0)
这是证书固定。这是正确的方法。您可以在手机中安装 https 证书,使用 fiddler 或 charles 进行测试。如果请求不成功,那么固定工作正常。通过禁用ssl固定来测试它。在这种情况下,请求将成功,您将能够在fiddler或charles中看到request + data
您还可以使用公钥锁定来锁定证书内的公钥
我已实施以下方式
InputStream cert = context.getResources().openRawResource(R.raw.certificate);
CertificateFactory cf=CertificateFactory.getInstance("X.509", "BC");
InputStream caInput = new BufferedInputStream(cert);
X509Certificate ca = (X509Certificate) cf.generateCertificate(caInput);
caInput.close();
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setCertificateEntry(ca.getSubjectX500Principal().getName(), ca);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, null);
KeyManager[] keyManagers = kmf.getKeyManagers();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext context1 = SSLContext.getInstance("TLS");
context1.init(keyManagers, tmf.getTrustManagers(), null);
builder.sslSocketFactory(context1.getSocketFactory());
答案 1 :(得分:0)
你正在做的是正确的方式。我也是按照你实施的方式做到的。它很好用。快乐编码:)
答案 2 :(得分:0)
在此处查看示例https://square.github.io/okhttp/https/#certificate-pinning-kt-java
private val client = OkHttpClient.Builder()
.certificatePinner(
CertificatePinner.Builder()
.add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
.build())
.build()
提醒:未经服务器TLS管理员的祝福,请勿使用证书固定!