在 Android (Java/Kotlin) 上获取 X.509 证书 ECDH 私有和 public 密钥
Get X.509 Certificate ECDH private and public key on Android (Java/Kotlin)
我目前正在尝试在我的 android 应用程序中实施 ECDH 算法。
但我遇到了一个问题,我想将私钥和 public 密钥存储在 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 以防你问。
如果有人能帮助我,我将不胜感激!
谢谢大家
好的,我解决这个问题的方法是将加密的私钥保存在 sharedpref 中。我知道它不是最好的,但我已经使用由 Android 密钥库处理的 AES 密钥对其进行了加密。除非 AES 被破解,否则没有密钥是无法解密的。
我目前正在尝试在我的 android 应用程序中实施 ECDH 算法。 但我遇到了一个问题,我想将私钥和 public 密钥存储在 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 以防你问。
如果有人能帮助我,我将不胜感激! 谢谢大家
好的,我解决这个问题的方法是将加密的私钥保存在 sharedpref 中。我知道它不是最好的,但我已经使用由 Android 密钥库处理的 AES 密钥对其进行了加密。除非 AES 被破解,否则没有密钥是无法解密的。