【问题标题】:Android - Connecting to backend server using public crt and private pem filesAndroid - 使用公共 crt 和私有 pem 文件连接到后端服务器
【发布时间】:2021-06-30 07:22:40
【问题描述】:

我正在开发一个应用程序,我必须在其中使用证书(在 .crt 文件中)和私钥(在 .pem 文件中)与后端服务器通信。

问题是——当我使用curl时,连接成功

curl (...) --cert pubcert.crt --key privkey.pem

但是当我尝试从 Android 应用程序连接时,我得到了

HTTP FAILED: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

我的 OkHttpClient:

        val privKeyInputStream = context.resources.openRawResource(R.raw.privkey)
        val pubKeyInputStream = context.resources.openRawResource(R.raw.pubcert)

        val cf: CertificateFactory = CertificateFactory.getInstance("X.509")
        val certificate: X509Certificate = cf.generateCertificate(pubKeyInputStream) as X509Certificate

        val keyPair = KeyPair(certificate.publicKey, loadPrivateKey(privKeyInputStream))

        val rootCertificate = HeldCertificate(keyPair, certificate)

        val certificates: HandshakeCertificates = HandshakeCertificates.Builder()
            .addTrustedCertificate(rootCertificate.certificate)
            .build()

        return OkHttpClient
            .Builder()
            .sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager)
            .build()
fun loadPrivateKey(inputStream: InputStream): PrivateKey? {
    var key: PrivateKey? = null
    try {
        val br = BufferedReader(InputStreamReader(inputStream))
        val builder = StringBuilder()
        var inKey = false
        var line = br.readLine()
        while (line != null) {
            if (!inKey) {
                if (line.startsWith("-----BEGIN ") &&
                    line.endsWith(" PRIVATE KEY-----")
                ) {
                    inKey = true
                }
                line = br.readLine()
                continue
            } else {
                if (line.startsWith("-----END ") &&
                    line.endsWith(" PRIVATE KEY-----")
                ) {
                    inKey = false
                    break
                }
                builder.append(line)
            }
            line = br.readLine()
        }
        println(builder.toString())
        //
        val encoded: ByteArray = Base64.decode(builder.toString(), Base64.DEFAULT)
        val keySpec = PKCS8EncodedKeySpec(encoded)
        val kf = KeyFactory.getInstance("RSA")
        key = kf.generatePrivate(keySpec)
    } finally {
        inputStream.close()
    }
    return key
}

【问题讨论】:

    标签: android kotlin ssl


    【解决方案1】:

    好的,我找到了解决方案,我将 HandshakeCertificates 定义更改为:

    val certificates: HandshakeCertificates = HandshakeCertificates.Builder()
                .addPlatformTrustedCertificates()
                .heldCertificate(HeldCertificate(keyPair, certificate))
                .build()
    

    现在可以了

    【讨论】:

      猜你喜欢
      • 2020-02-04
      • 2017-05-21
      • 1970-01-01
      • 2018-05-02
      • 2019-12-18
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      • 2012-10-26
      相关资源
      最近更新 更多