【问题标题】:Android Keystore decrypting encrypted data gives incorrect resultAndroid Keystore 解密加密数据给出不正确的结果
【发布时间】:2018-12-14 15:51:22
【问题描述】:

我正在尝试使用由java.security.KeyPairGenerator 的实例生成的密钥对来加密任意字符串。不幸的是,使用生成的 KeyPair 对字符串进行加密和解密后,结果不正确。

这就是我的做法:

val ks: KeyStore = KeyStore.getInstance("AndroidKeyStore").apply {
    load(null)
}

fun encryptUsingKey(publicKey: PublicKey, bytes: ByteArray): ByteArray {
    val inCipher = Cipher.getInstance("RSA/NONE/NoPadding")
    inCipher.init(Cipher.ENCRYPT_MODE, publicKey)
    return inCipher.doFinal(bytes)
}

fun decryptUsingKey(privateKey: PrivateKey, bytes: ByteArray): ByteArray {
    val inCipher = Cipher.getInstance("RSA/NONE/NoPadding")
    inCipher.init(Cipher.DECRYPT_MODE, privateKey)
    return inCipher.doFinal(bytes)
}

fun getKey(): KeyStore.Entry {
    val containsAlias = ks.containsAlias(alias)
    if (!containsAlias) {
        val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_RSA,
            "AndroidKeyStore"
        )
        val parameterSpec: KeyGenParameterSpec =
            KeyGenParameterSpec.Builder(
                alias,
                KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_ENCRYPT
            )
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                .setRandomizedEncryptionRequired(false)
                .build()

        kpg.initialize(parameterSpec)

        val kp = kpg.generateKeyPair()
    }
    return ks.getEntry(alias, null)
}

我的加密/解密测试如下:

fun testEncryptionDecryption() {
    val entry = getKey()

    if (entry is KeyStore.PrivateKeyEntry) {
        val privateKey = entry.privateKey
        val certificate = entry.certificate
        val publicKey = certificate.publicKey

        val testKey = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"

        val encrypted = service.encryptUsingKey(publicKey, Base64.decodeFromString(testKey))
        val decrypted = service.decryptUsingKey(privateKey, encrypted)

        assertEquals(testKey, Base64.encodeToString(decrypted))

    }
}

不幸的是,结果如下所示:

org.junit.ComparisonFailure: expected:<[0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF]> but was:<[AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANNdt-Oeu_PQAQgxBdNdt-Oeu_PQAQgxBdNdt-Oeu_PQAQgxBdNdt-Oeu_PQAQgxBQ]>

有人可以告诉我这里发生了什么吗?所有这些 A 是从哪里来的?我是不是用错了钥匙?

【问题讨论】:

  • 将 RSA 与 NoPadding 一起使用既不安全也不正确。 RSA解密需要知道明文的长度。 RSA 随机填充处理了这一点以及安全需求。 OAEP 填充是目前最适合 RSA 的,所以使用它,
  • @JamesKPolk 我试图采纳您的建议,但现在我收到了 java.security.InvalidKeyException: Keystore operation failed 异常...
  • 您是否更改了setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 以反映您使用的填充?
  • 是的,我将其设置为 KeyProperties.ENCRYPTION_PADDING_RSA_OAEP 并使用 Cipher.getInstance("RSA/NONE/OAEPPadding") 获取密码
  • @AKroell 你为什么使用 RSA? AES 会更快(耗电量更少),而且看起来您实际上并不需要 RSA 的非对称属性。

标签: android encryption kotlin android-keystore


【解决方案1】:

怀疑是配置不正确。以下作品:

val inCipher = Cipher.getInstance("RSA/ECB/OAEPPadding")

val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_RSA,
            "AndroidKeyStore"
        )
        val parameterSpec: KeyGenParameterSpec =
            KeyGenParameterSpec.Builder(
                alias,
                KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_ENCRYPT
            )
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                .setDigests(KeyProperties.DIGEST_SHA1)
                .build()

        kpg.initialize(parameterSpec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多