【发布时间】:2023-04-03 18:05:01
【问题描述】:
我正在尝试为此目的生成一个 RSA 密钥对:
val purposes = PURPOSE_DECRYPT or PURPOSE_ENCRYPT or PURPOSE_SIGN or PURPOSE_VERIFY
这是我的密钥生成代码:
val generator = KeyPairGenerator.getInstance(
KEY_ALGORITHM,
ANDROID_KEY_STORE
)
generator?.initialize(
KeyGenParameterSpec.Builder(
alias,
purposes
)
.setDigests(KeyProperties.DIGEST_SHA256)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.build()
)
generator?.generateKeyPair()
但是,当我使用此目的时,解密不起作用并引发异常:
InvalidKeyException: "keystore operation failed. Incompatible purpose."
但是当我只尝试加密和解密时,密钥库确实可以完美地加密和解密。这是我使用的目的:
val purposes = PURPOSE_DECRYPT or PURPOSE_ENCRYPT
这些是加密和解密的方法:
private fun decrypt(cipherText: String, alias: String): String? {
return try {
val privateKeyEntry = getGeneratedPrivateKey(alias)
val output = Cipher.getInstance(
"$KEY_ALGORITHM_RSA/$BLOCK_MODE_ECB/$ENCRYPTION_PADDING_RSA_PKCS1"
// ANDROID_OPEN_SSL
)
output.init(Cipher.DECRYPT_MODE, privateKeyEntry?.privateKey)
val inputStream = ByteArrayInputStream(
android.util.Base64.decode(
cipherText,
android.util.Base64.NO_WRAP
)
)
val res = String(CipherInputStream(inputStream, output).readBytes(), Charsets.UTF_8)
res
} catch (e: Exception) {
e.printStackTrace()
null
}
}
private fun encrypt(plainText: String, alias: String): String? {
return try {
val publicKey = getGeneratedPublicKey(alias) ?: setupKeyPair(
alias,
PURPOSE_ENCRYPT or PURPOSE_DECRYPT
)?.public
val cipher = Cipher.getInstance(
"$KEY_ALGORITHM_RSA/$BLOCK_MODE_ECB/$ENCRYPTION_PADDING_RSA_PKCS1"
// ANDROID_OPEN_SSL
)
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
val outputStream = ByteArrayOutputStream()
val cipherOutputStream = CipherOutputStream(outputStream, cipher)
cipherOutputStream.write(plainText.toByteArray(charset("UTF-8")))
cipherOutputStream.close()
val encryptedText = outputStream.toByteArray()
outputStream.close()
val res = android.util.Base64.encodeToString(encryptedText, android.util.Base64.NO_WRAP)
res
} catch (e: Exception) {
e.printStackTrace()
null
}
}
那么问题是什么?如何在 Android 密钥库中创建多用途密钥对?
【问题讨论】:
-
我不太了解 Kotlin,但您似乎混合了适当限定的常量(例如
KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)和实际上来自您的类的具有完全相同名称的常量(例如 @ 987654327@)。因此,我无法遵循您的代码。也许 Kotlin 专家可以。 -
@JamesReinstateMonicaPolk,问题与您的解释相似,但这是因为目的本身而不是填充。
标签: android encryption rsa android-keystore