我目前正在尝试在我的Android应用中实现ECDH算法。但是我遇到了一个问题,我想将私钥和公钥存储在Android KeyStore中。但是,为了实现这一点,我需要为我的keyPair获得证书。那就是我被困住的地方。
我无法获得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。
如果有人能够帮助我,我将非常感激!谢谢大家。
好的,我解决此问题的方法是将加密的私钥保存在sharedpref中。我知道这不是最好的方法,但我已使用由Android密钥存储区处理的AES密钥对其进行了加密。除非AES被破解,否则没有密钥就无法解密。