【发布时间】:2020-01-25 22:06:59
【问题描述】:
我目前正在尝试在我的 Android 应用中实现 ECDH 算法。 但我面临一个问题,我想将私钥和公钥存储在 Android KeyStore 中。但是,为了实现这一点,我需要为我的密钥对获得证书。这就是我卡住的地方。
我无法获得 Android KeyStore 允许使用的正确证书。
这是我生成密钥的方式(精简版)
val ecParamSpec = ECGenParameterSpec("secp521r1")
val keyPairGenerator = KeyPairGenerator.getInstance("ECDH", "SC")
keyPairGenerator.initialize(ecParamSpec, SecureRandom())
val keyPair = keyPairGenerator.generateKeyPair()
val privateKey = keyPair.private
val publicKey = keyPair.public
对于证书,我尝试了这个(使用 SHA256WithECDSA)
val startDate = Calendar.getInstance()
val endDate = Calendar.getInstance().apply {
add(Calendar.YEAR, 20)
}
val certBuilder = X509v3CertificateBuilder(
X500Name("CN=MASTERKEY CA Certificate"),
BigInteger.valueOf(System.currentTimeMillis()),
startDate.time,
endDate.time,
X500Name("DN=MASTERKEY CA Certificate"),
SubjectPublicKeyInfo.getInstance(keyPair.public.encoded)
)
val builder = JcaContentSignerBuilder("SHA256WithECDSA")
val signer = builder.build(keyPair.private)
val certBytes = certBuilder.build(signer).encoded
val certificateFactory = CertificateFactory.getInstance("X.509")
val certificate = certificateFactory.generateCertificate(ByteArrayInputStream(certBytes)) as X509Certificate
这很容易理解,因为 JcaContentSignerBuilder 算法与 KeyPairGenerator 不同,所以这不起作用。这就是 Android KeyStore 开始告诉我有问题的地方。
java.lang.IllegalArgumentException: private key algorithm does not match algorithm of public key in end entity certificate (at index 0)
我使用此代码尝试将密钥存储在 Android KeyStore 中
keyStore.setEntry("MASTERKEY", KeyStore.PrivateKeyEntry(key[DH.PRIVATE_KEY] as PrivateKey, arrayOf(key[DH.CERTIFICATE] as Certificate)),
KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_SIGN).setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
.build())
我正在使用 spongycastle 以防你问。
如果有人能帮助我,我将不胜感激! 谢谢大家。
【问题讨论】:
-
您能否尝试为密钥对生成器指定
"EC"甚至"ECDSA"?因为这些键是相同的但对于算法规范。然后您可以获得私钥,并希望它仍然适用于您的密钥协议。您还可以创建两个证书链,在其中创建 ECDH 证书并使用基于自签名 ECDSA 的证书对其进行签名,但这似乎更有效,而且我不知道证书生成器是否支持基于 ECDH 的证书。跨度> -
可用于 ECDSA 和 ECDH 算法的密钥(对)类型 EC 对于 JavaSE 中的 BouncyCastle(以及 SunEC)绝对正确。通常,ECDH 证书的最佳实践是将 KeyUsage 扩展设置为允许 keyAgree 并禁止 digSign,但如果您从不共享此证书也没关系。自签名证书应该具有 issuer=subject,但您在一个中使用了 CN(常见),在另一个中使用了 DN(不同且极为罕见)。
标签: encryption kotlin cryptography certificate diffie-hellman