【发布时间】:2019-07-15 15:15:57
【问题描述】:
无法使用 AndroidKeystore 提供程序一
根据AndroidKeyStore documentation
在 API 级别 23 之前,可以使用算法“RSA”的 KeyPairGenerator 生成 EC 密钥,该算法初始化 KeyPairGeneratorSpec,其密钥类型使用 setKeyType(String) 设置为“EC”。使用此方法无法指定 EC 曲线名称 - NIST P 曲线会根据请求的密钥大小自动选择。
在 Api 23 以下,我应该能够使用 AndroidKeyStore 提供程序生成一个 EC 密钥对,如下所示的代码 sn-p 这是我目前正在做的。
val ecGenParameterSpec = ECGenParameterSpec("P-256")
val spec = KeyPairGeneratorSpec.Builder(context)
.setAlias(ALIAS)
.setSubject(X500Principal("CN=example"))
.setSerialNumber(BigInteger.ONE)
.setKeyType("EC")
.setAlgorithmParameterSpec(ecGenParameterSpec)
.setStartDate(start)
.setEndDate(end)
.build()
val keyGen = KeyPairGenerator.getInstance("RSA", androidKeyStoreProvider)
keyGen.initialize(spec, SecureRandom())
keyGen.generateKeyPair()
但是我不断收到java.lang.UnsupportedOperationException: private key value S cannot be extracted。
在使用 AndroidKeyStore 生成 EC 密钥对的过程中我做错了吗?
还是我将官方的AndroidKeyStore documentation 误解为KeyPairGenerator?
下面是我尝试使用的设备之一(一加一)的堆栈跟踪。 我在 api 21 和 22 上尝试过多个设备。
设备 - 华硕 zenfone2 (api21)、nexus 4(api22)、一加一(api22)、redmi note2 (api21)
No pending exception expected: java.lang.UnsupportedOperationException: private key value S cannot be extracted
at java.math.BigInteger com.android.org.conscrypt.OpenSSLECPrivateKey.getS() (OpenSSLECPrivateKey.java:141)
at com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil.gen
eratePrivateKeyParameter(java.security.PrivateKey) (ECUtil.java:188)
at void com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi.engineInitSign(java.security.PrivateKey) (SignatureSpi.java:
61)
at void java.security.Signature$SignatureImpl.engineInitSign(java.security.PrivateKey) (Signature.java:679)
at void java.security.Signature.initSign(java.security.PrivateKey) (Signature.java:330)
at byte[] org.conscrypt.CryptoUpcalls.signDigestWithPrivateKey(java.security.PrivateKey, byte[], java.lang.String) (SourceFile:101)
at byte[] org.conscrypt.CryptoUpcalls.ecSignDigestWithPrivateKey(java.security.PrivateKey, byte[]) (SourceFile:67)
at byte[] org.conscrypt.NativeCrypto.EVP_DigestSignFinal(org.conscrypt.NativeRef$EVP_MD_CTX) (SourceFile:-2)
at byte[] org.conscrypt.OpenSSLSignature.engineSign() (SourceFile:226)
at byte[] java.security.Signature$SignatureImpl.engineSign() (Signature.java:659)
at byte[] java.security.Signature.sign() (Signature.java:368)
at byte[] com.android.org.bouncycastle.x509.X509Util.calculateSignature(com.android.org.bouncycastle.asn1.DERObjectIdentifier, java.lang.Str
ing, java.security.PrivateKey, java.security.SecureRandom, com.android.org.bouncycastle.asn1.ASN1Encodable) (X509Util.java:248)
at java.security.cert.X509Certificate com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(java.security.PrivateKey, java.s
ecurity.SecureRandom) (X509V3CertificateGenerator.java:434)
at java.security.cert.X509Certificate com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(java.security.PrivateKey) (X509V
3CertificateGenerator.java:412)
at java.security.KeyPair android.security.AndroidKeyPairGenerator.generateKeyPair() (AndroidKeyPairGenerator.java:133)
at java.security.KeyPair java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair() (KeyPairGenerator.java:276)
更新
发现问题,我在我的应用程序中使用了 Google Conscrypt Android。
Security.insertProviderAt(Conscrypt.newProvider(), 1)
不知何故,当我在我的应用程序中使用 Conscrypt 提供程序时,AndroidKeyStore 无法生成 EC 密钥对。 取消使用 Conscrypt 似乎可以解决问题。
【问题讨论】:
标签: android android-keystore android-security