gpt4 book ai didi

客户端证书的Android okhttp3错误

转载 作者:行者123 更新时间:2023-12-03 20:58:51 38 4
gpt4 key购买 nike

我对使用 okhttp3 库发出 https 请求的 android native 应用程序有问题。我必须使用客户端证书进行身份验证。问题是当我调用 build HandshakeCertificates.Builder的功能它抛出 NullPointerException获得一些 的长度字符串 (我不知道它是什么字符串)。我发现只有当我调用 heldCertificate 时才会发生这种情况在构建之前。

我能够调试 KeyStore.setKeyEntry在哪里打电话BcKeyStoreSpi.engineSetKeyEntry带有别名、 key 、密码和链参数。它们都不是空的,我认为它们具有正确的值(但我不是证书专家,所以可能缺少一些东西)。我无权访问 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) 

    最佳答案

    您无法提取 key 来填充另一个 keystore 。相反,您应该使用与本文类似的自定义 keystore 。
    https://medium.com/@_kbremner/android-and-client-authentication-fd416af19a04

            KeyChain.choosePrivateKeyAlias(this,
    { alias -> storeAlias(alias) },
    arrayOf("RSA", "DSA"), // List of acceptable key types. null for any
    null, // issuer, null for any
    null, // host name of server requesting the cert, null if unavailable
    443, // port of server requesting the cert, -1 if unavailable
    null) // alias to preselect, null if unavailable
    关键代码将是
    val pk = KeyChain.getPrivateKey(applicationContext, alias)!!
    val chain = KeyChain.getCertificateChain(applicationContext, alias)!!


    val km = object : X509KeyManager {
    override fun getClientAliases(keyType: String?, issuers: Array<Principal>): Array<String> {
    return arrayOf(alias)
    }

    override fun chooseClientAlias(keyType: Array<out String>?, issuers: Array<out Principal>?, socket: Socket?): String {
    return alias
    }

    override fun getServerAliases(keyType: String?, issuers: Array<Principal>): Array<String> {
    return arrayOf()
    }

    override fun chooseServerAlias(keyType: String?, issuers: Array<Principal>, socket: Socket): String {
    return ""
    }

    override fun getCertificateChain(alias: String?): Array<X509Certificate> {
    return chain
    }

    override fun getPrivateKey(alias: String?): PrivateKey {
    return pk
    }
    }

    val sslContext = SSLContext.getInstance("TLS")
    sslContext.init(arrayOf(km), trustManagers, null)

    val client: OkHttpClient = OkHttpClient.Builder()
    .sslSocketFactory(sslContext.socketFactory, trustManagers[0] as X509TrustManager)
    .build()

    关于客户端证书的Android okhttp3错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59422820/

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