You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Android设备生成的KeyPair替换Google硬件证明根证书?

实现以Google硬件Attestation根证书为信任锚的密钥对

你不能直接将密钥的自签名证书替换成Google硬件Attestation根证书——因为根证书是CA的信任锚,你的密钥对应的证书必须是由Google Attestation CA链签发的、绑定你公钥的证书。正确的做法是生成支持硬件Attestation的密钥对,然后获取它的Attestation证书链,这个链的最终根就是Google的硬件Attestation根证书。

步骤1:修改密钥生成代码,开启硬件Attestation支持

需要在KeyGenParameterSpec.Builder中添加Attestation相关配置,确保密钥支持硬件级别的Attestation:

private fun generateAttestedKeyPairAndGetChain(): Array<X509Certificate>? {
    val keyStore = KeyStore.getInstance("AndroidKeyStore")
    keyStore.load(null)

    // 先删除已存在的同名密钥(如果有)
    if (keyStore.containsAlias("my-mobile-key")) {
        keyStore.deleteEntry("my-mobile-key")
    }

    val keyPairGenerator = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"
    )

    // 生成Attestation挑战(任意字节数组,用于防止重放攻击)
    val attestationChallenge = "MyAttestationChallenge".toByteArray(Charsets.UTF_8)

    keyPairGenerator.initialize(
        KeyGenParameterSpec.Builder(
            "my-mobile-key",
            KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_ENCRYPT
        )
            .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
            .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
            // 开启硬件Attestation支持
            .setAttestationChallenge(attestationChallenge)
            // 可选:若设备支持StrongBox,强制密钥存储在StrongBox中
            .setIsStrongBoxBacked(true)
            .build()
    )

    keyPairGenerator.generateKeyPair()

    // 获取包含Attestation证书链的密钥条目
    val keyEntry = keyStore.getEntry("my-mobile-key", null) as KeyStore.PrivateKeyEntry
    return keyEntry.certificateChain as? Array<X509Certificate>
}

步骤2:验证证书链的根是Google硬件Attestation根证书

获取到证书链后,你需要验证链的最终根证书是否匹配Google的硬件Attestation根证书(可通过证书的Subject或公钥哈希比对):

private fun validateAttestationRoot(chain: Array<X509Certificate>): Boolean {
    // 获取链的根证书(链的最后一个元素)
    val rootCert = chain.last()

    // Google硬件Attestation根证书的标准Subject DN
    val expectedRootSubject = "CN=Google Hardware Attestation Root, O=Google LLC, L=Mountain View, ST=California, C=US"
    
    // 验证Subject匹配
    if (rootCert.subjectDN.name != expectedRootSubject) {
        return false
    }

    // 可选:通过公钥SHA256哈希验证(更安全,需替换为实际的Google根证书公钥哈希)
    val pubKeyBytes = rootCert.publicKey.encoded
    val sha256 = MessageDigest.getInstance("SHA-256").digest(pubKeyBytes)
    val pubKeySha256Hex = sha256.joinToString("") { "%02x".format(it) }
    val expectedRootPublicKeySha256 = "f80a0f386bb25c22c5c44838ed00c761c10a4c4c9ff0c5f0e31c7f31e9a0060d"
    
    return pubKeySha256Hex.equals(expectedRootPublicKeySha256, ignoreCase = true)
}

关键说明

  • 为什么不能直接替换证书?:AndroidKeyStore要求密钥必须绑定证书,自签名证书是初始占位符,但只有通过Google的Attestation流程生成的证书链,才能证明你的密钥是在硬件安全模块中生成的,且符合安全要求。直接替换根证书没有意义,因为根证书不包含你的公钥,无法用于验证你的密钥签名或加密操作。
  • Attestation版本要求:需要Android 7.0(API 24)及以上版本,且设备的AndroidKeyStore支持硬件级密钥存储(大部分现代Android设备都支持)。
  • Challenge的作用:setAttestationChallenge传入的字节数组用于绑定Attestation请求的上下文,防止攻击者重放已生成的Attestation证书。

内容的提问来源于stack exchange,提问作者Sacha.R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 15:42:46