Java 生成的Android密钥对不';我没有证书链来证明

Java 生成的Android密钥对不';我没有证书链来证明,java,android,security,encryption,public-key-encryption,Java,Android,Security,Encryption,Public Key Encryption,我使用以下代码在Android设备(8.1/API级别27)上生成密钥对: KeyGenParameterSpec spec=新建KeyGenParameterSpec.Builder( 密钥别名, KeyProperties.PURPOSE_符号| KeyProperties.PURPOSE_验证 ) .setDigests(KeyProperties.DIGEST_SHA256,keyperties.DIGEST_SHA512) .setCertificateSubject(新的X500主体

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

KeyGenParameterSpec spec=新建KeyGenParameterSpec.Builder(
密钥别名,
KeyProperties.PURPOSE_符号| KeyProperties.PURPOSE_验证
)
.setDigests(KeyProperties.DIGEST_SHA256,keyperties.DIGEST_SHA512)
.setCertificateSubject(新的X500主体(“CN=X,O=X”))
.setCertificateSerialNumber(BigInteger.ONE)
.setSignaturePaddings(KeyProperties.SIGNATURE\u PADDING\u RSA\u PKCS1)
.setEncryptionPaddings(KeyProperties.ENCRYPTION\u PADDING\u RSA\u PKCS1)
.build();
KeyPairGenerator generator=KeyPairGenerator.getInstance(“RSA”、“AndroidKeyStore”);
生成器初始化(规范);
generator.generateKeyPair();
然后我想证明生成的证书由google根证书签名,以证明证书存储在TEE中(请参阅):

KeyStore.PrivateKeyEntry PrivateKeyEntry=(KeyStore.PrivateKeyEntry)密钥库
.getEntry(键别名,null);
KeyFactory KeyFactory=KeyFactory.getInstance(
privateKeyEntry.getPrivateKey().getAlgorithm(),
“AndroidKeyStore”
);
KeyInfo KeyInfo=keyFactory.getKeySpec(privateKeyEntry.getPrivateKey(),KeyInfo.class);
Log.i(标记“是安全硬件中的密钥:+keyInfo.isInsideSecureHardware());
Log.i(标记,“链中的证书数:”+privateKeyEntry.getCertificateChain().length);
返回:

Is key in secure hardware: true
Number of certificates in the chain: 1
链中唯一的证书是包含生成的公钥的证书。而且它不需要证明


如何生成密钥对,以便有一个带有扩展数据的证书链进行认证?

您需要通过调用
KeyGenParameterSpec.Builder
实例上的
SetDetectionChallenge
来显式请求硬件认证,并向其传递服务器端生成的nonce

这将导致Android密钥库使用OEM提供的受硬件保护的密钥对公钥证书进行签名(该密钥本身由Google提供的中间CA密钥签名,中间CA密钥由Google根CA密钥签名)


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

您需要通过调用
KeyGenParameterSpec.Builder
实例上的
setDetectionChallenge
来显式请求硬件认证,并向其传递服务器端生成的nonce

这将导致Android密钥库使用OEM提供的受硬件保护的密钥对公钥证书进行签名(该密钥本身由Google提供的中间CA密钥签名,中间CA密钥由Google根CA密钥签名)


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

AndroidKeyStore仅根据定义生成。但是,可以导入现有的证书+密钥。嗨@Robert,谢谢,现在就可以了。您知道如何从TEE导出现有证书和公钥吗?使用
KeyStore
接口访问
AndroidKeyStore
,因此只需使用
KeyStore.getInstance(“AndroidKeyStore”)
并像其他任何密钥库一样使用它(除了不能读取私钥这一事实)。据我从您最初的评论
AndroidKeyStore
中了解,AndroidKeyStore只保留自签名证书。如何导出可认证的android签名证书?不,它只生成自签名证书。如果您导入证书,它可以保留您想要的任何证书。AndroidKeyStore仅根据定义生成。但是,可以导入现有的证书+密钥。嗨@Robert,谢谢,现在就可以了。您知道如何从TEE导出现有证书和公钥吗?使用
KeyStore
接口访问
AndroidKeyStore
,因此只需使用
KeyStore.getInstance(“AndroidKeyStore”)
并像其他任何密钥库一样使用它(除了不能读取私钥这一事实)。据我从您最初的评论
AndroidKeyStore
中了解,AndroidKeyStore只保留自签名证书。如何导出可认证的android签名证书?不,它只生成自签名证书。如果你导入证书,它可以保存你想要的任何证书。