简体   繁体   English

未找到认证路径的信任锚。 在 android 上使用自签名客户端证书

[英]Trust anchor for certification path not found. Using self-signed client certificates on android

I have a simple web api running on a raspberry pi that sits behind an nginx server on the same pi.我有一个简单的 web api 在树莓派上运行,它位于同一个 pi 上的 nginx 服务器后面。 I'm using self-signed client certificates to authenticate calls from an android app.我正在使用自签名客户端证书来验证来自 android 应用程序的调用。 This worked completely fine in the past, but I recently came back to this project after rebuilding some hardware, and when I try and use it on my Pixel 2 running Android 8.1, it gives the following exception:这在过去完全正常,但我最近在重建一些硬件后又回到了这个项目,当我尝试在运行 Android 8.1 的 Pixel 2 上使用它时,它给出了以下异常:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
    at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:219)
    at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:268)
    ...

I generated certs and keys according to: http://nategood.com/client-side-certificate-authentication-in-ngi我根据: http : //nategood.com/client-side-certificate-authentication-in-ngi生成了证书和密钥

Testing with curl works fine.使用curl测试工作正常。

I created keystore for the app to use with:我为应用程序创建了密钥库以用于:

openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

I followed the following article to setup the client certs in Android and connect to the server: http://chariotsolutions.com/blog/post/https-with-client-certificates-on/我按照以下文章在 Android 中设置客户端证书并连接到服务器: http : //chariotsolutions.com/blog/post/https-with-client-certificates-on/

but I rewrote it in Kotlin, using OkHttp:但我在 Kotlin 中使用 OkHttp 重写了它:

private const val SERVER = "https://my.server"

/**
* trustManagers is used to authorize the server's self-signed cert
*/
private val trustManagers by lazy {
    val cert = CertificateFactory.getInstance("X.509")
            .generateCertificate(appCtx.assets.open("ca.crt")) as X509Certificate

    val trustStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply {
        load(null, null)
        setCertificateEntry(cert.subjectX500Principal.name, cert)
    }

    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
        init(trustStore)
    }.trustManagers
}

/**
* keyManagers is used to load the client-authentication cert
*/
private val keyManagers by lazy {
    // assuming this can only be called after Application is created

    val keyStore = KeyStore.getInstance("PKCS12").apply {
        load(appCtx.assets.open("client.p12"), "".toCharArray())
    }

    KeyManagerFactory.getInstance("X509").apply {
        init(keyStore, "".toCharArray())
    }.keyManagers
}

/**
* sslContext for opening TLS connection to server
*/
private val sslContext by lazy {
    SSLContext.getInstance("TLS").apply {
        init(keyManagers, trustManagers, null)
    }
}

/**
* pass an HTTPS request to server
*/
suspend fun request(url: String): ByteArray? {
    return try {
        val request = Request.Builder()
                .url(url)
                .build()
        val client = OkHttpClient.Builder()
                .sslSocketFactory(sslContext.socketFactory, trustManagers[0] as X509TrustManager)
                .build()
        client.newCall(request).await().body().byteStream().readBytes()
    } catch (e: Exception) {
        err(e) { "failed to send request" }
        null
    }
}

This use to work, but now it does not.使用工作,但现在它没有。 I spent a day and a half searching for an answer and I've tried the following:我花了一天半的时间寻找答案,并尝试了以下方法:

  • I've tried using HttpURLConnection instead of OkHttp我试过使用 HttpURLConnection 而不是 OkHttp
  • I've tried re-creating all the certs/keys from scratch.我尝试从头开始重新创建所有证书/密钥。
  • I've tried using the new "Network Security Configuration":我试过使用新的“网络安全配置”:

<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <!-- Additionally trust user added CAs --> <certificates src="user" /> <certificates src="@raw/ca"/> </trust-anchors> </base-config> </network-security-config>

I've read all the examples I can find on creating custom trust managers, and they are all pretty much the same, even https://developer.android.com/training/articles/security-ssl.html#UnknownCa我已经阅读了所有关于创建自定义信任管理器的示例,它们几乎都相同,甚至是https://developer.android.com/training/articles/security-ssl.html#UnknownCa

Everythign I've tried produces the same exception, am I missing something?我试过的一切都会产生同样的异常,我错过了什么吗?

This is how I was able to get it to work in my project, using a self-signed cert on GoDaddy:这就是我使用 GoDaddy 上的自签名证书让它在我的项目中工作的方式:

  1. In your project, in Android Studio, create a new directory named 'raw' (no single quotes)在您的项目中,在 Android Studio 中,创建一个名为 'raw' 的新目录(无单引号)
  2. Create a new text file in the raw folder with any name and the .crt extension (IE gdCert.crt)在原始文件夹中创建一个具有任何名称和 .crt 扩展名的新文本文件 (IE gdCert.crt)
  3. On the GoDaddy cPanel, under Security, click 'SSL/TLS'.在 GoDaddy cPanel 上的“安全”下,单击“SSL/TLS”。 Click the link under 'Certificates' and then it should show you the certificate you have already created.单击“证书”下的链接,然后它应该会显示您已经创建的证书。 Click the 'Edit' link.单击“编辑”链接。 Select and copy the contents of the certificate and paste that into the text file you created in the Android Studio 'raw' folder and save it.选择并复制证书的内容,然后将其粘贴到您在 Android Studio 'raw' 文件夹中创建的文本文件中并保存。
  4. In Android Studio, right click the 'res' folder, New > XML > App Actions XML File.在 Android Studio 中,右键单击“res”文件夹,新建 > XML > App Actions XML 文件。 Name this file 'network_security_config' (no single quotes)将此文件命名为“network_security_config”(无单引号)
  5. Add the following to the 'network_security_config.xml' file:将以下内容添加到“network_security_config.xml”文件中:

 <?xml version="1.0" encoding="utf-8"?> <network-security-config> <debug-overrides> <trust-anchors> <certificates src="user"/> <certificates src="@raw/gdcert"/> </trust-anchors> </debug-overrides> </network-security-config>

  1. In your AndroidManifest.xml file, add the following under the <application node:在您的 AndroidManifest.xml 文件中,在 <application 节点下添加以下内容:

 android:networkSecurityConfig="@xml/network_security_config"

  1. Use the following java code in your solution:在您的解决方案中使用以下 java 代码:

 SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); SSLSocketFactory ssf = sc.getSocketFactory(); SSLSocket sslsocket = (SSLSocket) ssf.createSocket("yourwebsitename.com", 443);

Followed by whatever code you are trying to run to connect to the server.其次是您尝试运行以连接到服务器的任何代码。

  1. Note that the second line calls a new method which should be added to your class:请注意,第二行调用了一个应该添加到您的类中的新方法:

 TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }};

Save your project and run it.保存您的项目并运行它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Xamarin Android 问题通过 HTTPS 连接到使用自签名证书的站点:“未找到证书路径的信任锚。” - Xamarin Android issue connecting via HTTPS to site with self-signed certificate: "Trust anchor for certification path not found." Android volley自签名HTTPS信任锚,用于找不到证书路径 - Android volley self signed HTTPS trust anchor for certification path not found Android自签名证书:未找到证书路径的信任锚 - Android self signed certificate: Trust anchor for certification path not found android 未找到认证路径的信任锚。 我的后端没有自行分配的证书。 该怎么办? - android Trust anchor for certification path not found. My backend have not self assigned certificate. What to do? “未找到证书路径的信任锚”的问题。 - Problem with “Trust anchor for certification path not found.” 使用loopj时出错:“找不到用于认证路径的信任锚。” - Error when using loopj: “Trust anchor for certification path not found.”` Android:CertPathValidatorException:找不到证书路径的信任锚 - Android: CertPathValidatorException: Trust anchor for certification path not found Android 7:找不到认证路径的信任锚 - Android 7: Trust anchor for certification path not found 获取“未找到证书路径的信任锚”。 对于曾经有效的服务 - Getting “Trust anchor for certification path not found.” for a service that used to work 如何解决“找不到证书路径的信任锚”。 在 Xamarin 项目中? - How to resolve "trust anchor for certification path not found." in Xamarin Project?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM