【发布时间】:2020-04-12 19:46:30
【问题描述】:
我对使用 okhttp3 库发出 https 请求的 android 本机应用程序有疑问。我必须使用客户端证书进行身份验证。问题是当我调用HandshakeCertificates.Builder 的build 函数时,它会抛出NullPointerException 以获得一些 string 的长度(我不知道它是什么字符串)。我发现,只有在构建之前调用 heldCertificate 时才会发生这种情况。
我能够调试 KeyStore.setKeyEntry 使用别名、密钥、密码和链参数调用 BcKeyStoreSpi.engineSetKeyEntry 的位置。它们都不是空的,我认为它们具有正确的值(但我不是证书专家,所以可能缺少一些东西)。我无权访问 BcKeyStoreSpi.engineSetKeyEntry 的代码。
我在三星 Galaxy Tab A SM-T515 上使用带有工作配置文件的 Android 9 Enterprise。
依赖项(仅 okhttp 特定):
- 实现(“com.squareup.okhttp3:okhttp:4.1.0”)
- 实现(“com.squareup.okhttp3:okhttp-tls:4.1.0”)
有人可以帮帮我吗?谢谢
代码
PrivateKey privateKey = KeyChain.getPrivateKey(context, certAlias);
X509Certificate[] certChain = KeyChain.getCertificateChain(context, certAlias);
X509Certificate mdmCert = certChain[0];
HandshakeCertificates.Builder builder = new HandshakeCertificates.Builder();
builder.addPlatformTrustedCertificates();
for (X509Certificate cert : certChain) {
builder.addTrustedCertificate(cert);
}
builder.heldCertificate( //if this is commented then everything is ok
new HeldCertificate(
new KeyPair(
mdmCert.getPublicKey(),
privateKey
),
mdmCert
),
certChain
);
HandshakeCertificates clientCertificates = builder.build(); //this throws exception
堆栈跟踪
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:354)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.security.KeyStoreException: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi.engineSetKeyEntry(BcKeyStoreSpi.java:685)
at java.security.KeyStore.setKeyEntry(KeyStore.java:1179)
at okhttp3.tls.internal.TlsUtil.newKeyManager(TlsUtil.kt:85)
at okhttp3.tls.HandshakeCertificates$Builder.build(HandshakeCertificates.kt:144)
at cz.kctdata.skoenergo.ui.activity.MainActivity$GetCertAsyncTask.doInBackground(MainActivity.java:121)
at cz.kctdata.skoenergo.ui.activity.MainActivity$GetCertAsyncTask.doInBackground(MainActivity.java:85)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
【问题讨论】:
-
您解决了这个问题吗?
标签: android https okhttp client-certificates