Android Keystore 多用途密钥生成
Android Keystore multipurpose key generation
我正在尝试为此目的生成一个 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 密钥库中制作多用途密钥对?
可能您有自己的 purpose keys
自定义变量
您应该在这一行中使用 KeyProperties
:
val purposes = PURPOSE_DECRYPT or PURPOSE_ENCRYPT or PURPOSE_SIGN or PURPOSE_VERIFY
像这样:
val purposes = KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
我正在尝试为此目的生成一个 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 密钥库中制作多用途密钥对?
可能您有自己的 purpose keys
您应该在这一行中使用 KeyProperties
:
val purposes = PURPOSE_DECRYPT or PURPOSE_ENCRYPT or PURPOSE_SIGN or PURPOSE_VERIFY
像这样:
val purposes = KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY