【问题标题】:Generated Android key pair doesn't have certificate chain to attest生成的 Android 密钥对没有证书链来证明
【发布时间】:2019-08-31 03:29:03
【问题描述】:

我正在使用以下代码在 Android 设备(8.1 / API 级别 27)上生成密钥对:

KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
        KEY_ALIAS,
        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
    )
    .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
    .setCertificateSubject(new X500Principal("CN=X, O=X"))
    .setCertificateSerialNumber(BigInteger.ONE)
    .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
    .build();

KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
generator.initialize(spec);

generator.generateKeyPair();

然后我想证明生成的证书是由谷歌根证书签名的,以证明证书存储在 TEE 中(参见Verifying hardware-backed key pairs with Key Attestation):

KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keystore
    .getEntry(KEY_ALIAS, null);


KeyFactory keyFactory = KeyFactory.getInstance(
    privateKeyEntry.getPrivateKey().getAlgorithm(),
    "AndroidKeyStore"
);
KeyInfo keyInfo = keyFactory.getKeySpec(privateKeyEntry.getPrivateKey(), KeyInfo.class);

Log.i(TAG, "Is key in secure hardware: " + keyInfo.isInsideSecureHardware());
Log.i(TAG, "Number of certificates in the chain: " + privateKeyEntry.getCertificateChain().length);

返回:

Is key in secure hardware: true
Number of certificates in the chain: 1

链中唯一的证书是包含生成的公钥的证书。而且它没有certificate extension data 来证明它。

如何生成密钥对,以便拥有一个包含扩展数据的证书链来证明?

【问题讨论】:

  • AndroidKeyStore 仅根据定义生成self-signed certificates。但是,可以导入现有的证书 + 密钥。
  • 嗨@Robert,谢谢,现在说得通了。您知道如何从 TEE 导出现有证书和公钥吗?
  • AndroidKeyStore 使用KeyStore 接口访问,因此只需使用KeyStore.getInstance("AndroidKeyStore"); 并像使用任何其他密钥库一样使用它(除了您无法读取私钥这一事实之外)。
  • 据我了解,您最初的评论 AndroidKeyStore 仅保留自签名证书。如何导出可以证明的安卓签名证书?
  • 不,它生成只是自签名。 AFAIK 如果您导入它们,它可以保留您想要的任何证书。

标签: java android security encryption public-key-encryption


【解决方案1】:

您需要通过在 KeyGenParameterSpec.Builder 实例上调用 setAttestationChallenge 并传递一个服务器端生成的随机数来显式请求硬件证明。

这将导致 Android 密钥库使用其来自 OEM 的硬件保护密钥签署公钥证书(该密钥本身又由 Google 的中间 CA 密钥签名,该密钥由 Google 根 CA 密钥签名)。

然后,通过在 KeyStore 实例上调用 getCertificateChain 来获取完整链。

【讨论】:

    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 2011-10-16
    • 2016-10-26
    • 2018-12-04
    • 2018-12-12
    相关资源
    最近更新 更多