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