【问题标题】:Android Keystore multipurpose key generationAndroid Keystore 多用途密钥生成
【发布时间】: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


【解决方案1】:

您可能有自己的 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

【讨论】:

  • 猜得好,艾哈迈德!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2013-02-26
相关资源
最近更新 更多