Kotlin 使用非对称用户授权保护的密钥库密钥加密大字符串时出现问题

Kotlin 使用非对称用户授权保护的密钥库密钥加密大字符串时出现问题,kotlin,encryption,android-keystore,android-biometric,Kotlin,Encryption,Android Keystore,Android Biometric,我正在尝试为JWToken的加密和解密实现生物认证。 用户在服务器上进行身份验证后,将接收令牌并对其进行加密。加密 在没有生物特征用户授权的情况下,应允许在设备上使用令牌。 只有解密操作才需要生物识别设备授权。这就是为什么我 为此使用非对称密钥。然而,我收到的令牌大约是1000字节,因此 无法使用非对称密钥加密。这就是我创建对称密钥进行解密的原因 和加密操作,并使用受授权保护的非对称密钥包装和打开此密钥。 但是,尝试用非对称公钥包装对称密钥会引发InvalidKeyException with

我正在尝试为JWToken的加密和解密实现生物认证。 用户在服务器上进行身份验证后,将接收令牌并对其进行加密。加密 在没有生物特征用户授权的情况下,应允许在设备上使用令牌。 只有解密操作才需要生物识别设备授权。这就是为什么我 为此使用非对称密钥。然而,我收到的令牌大约是1000字节,因此 无法使用非对称密钥加密。这就是我创建对称密钥进行解密的原因 和加密操作,并使用受授权保护的非对称密钥包装和打开此密钥。 但是,尝试用非对称公钥包装对称密钥会引发InvalidKeyException with 消息:javax.crypto.BadPaddingException。尝试用非对称私钥包装对称密钥 这次还抛出InvalidKeyException,并显示简短消息:未能打开密钥。当我设置UserAuthenticationRequired时 若要使非对称私钥为false,则可以很好地进行包装。我做错了什么

class EncryptionService(
    private val wrappedKeyStoreSource: WrappedKeyStore2
) {

    companion object {
        const val MASTER_KEY = "master_key"
        const val ALGORITHM_AES = "AES"
        const val ENCRYPTION_KEY = "encryption_key"
        const val TRANSFORMATION_ASYMMETRIC = "RSA/ECB/PKCS1Padding"
        const val TRANSFORMATION_SYMMETRIC = "AES/CBC/PKCS7Padding"
    }

    private val keyStore: KeyStore = createAndroidKeyStore()

    init {
        createDefaultSymmetricKey()
    }

    fun encrypt(data: String): String =
        encryptWithSymmetricKey(data)

    private fun createDefaultSymmetricKey() {
        val symmetricKey = generateSymmetricKey()
        val masterKey = createAsymmetricKey(MASTER_KEY)
        val cipher: Cipher = Cipher.getInstance(TRANSFORMATION_ASYMMETRIC)
        cipher.init(Cipher.WRAP_MODE, masterKey.public)
        val encryptedSymmetricKey = cipher.wrap(symmetricKey)
        wrappedKeyStoreSource.saveKey(ENCRYPTION_KEY, Base64.encodeToString(encryptedSymmetricKey, Base64.DEFAULT) )
    }

    //encrypt without user authorization
    private fun encryptWithSymmetricKey(data: String): String {
        val masterKey = getAsymmetricKeyPair(MASTER_KEY)
        val encryptionKey = wrappedKeyStoreSource.getKey(ENCRYPTION_KEY)
        val unwrapCipher: Cipher = Cipher.getInstance(TRANSFORMATION_ASYMMETRIC)
        unwrapCipher.init(Cipher.UNWRAP_MODE, masterKey?.public)
        val encryptedKeyData = Base64.decode(encryptionKey, Base64.DEFAULT)

       //this line throws InvalidKeyException 
        //unwrap with public key throws InvalidKeyException with message: javax.crypto.BadPaddingException.
        //unwrap with private key throws InvalidKeyException if setUserAuthenticationRequired on this
        // key is set to true with message: Failed to unwrap key (maybe due to UserNotAuthenticatedException?)
        val symmetricKey = unwrapCipher.unwrap(encryptedKeyData, ALGORITHM_AES, Cipher.PUBLIC_KEY) as SecretKey

        val encryptCipher: Cipher = Cipher.getInstance(TRANSFORMATION_SYMMETRIC)
        encryptCipher.init(Cipher.ENCRYPT_MODE, symmetricKey)
        val encryptedString = encryptCipher.doFinal(data.toByteArray())
        return Base64.encodeToString(encryptedString, Base64.DEFAULT)
    }

    private fun createAsymmetricKey(alias: String): KeyPair {
        val generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore")
        val builder = KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
            .setUserAuthenticationRequired(true)
        generator.initialize(builder.build())
        return generator.generateKeyPair()
    }

    private fun generateSymmetricKey(): SecretKey {
        val keyGenerator = KeyGenerator.getInstance("AES")
        return keyGenerator.generateKey()
    }

    private fun getAsymmetricKeyPair(alias: String): KeyPair? {
        val privateKey = keyStore.getKey(alias, null) as PrivateKey?
        val publicKey = keyStore.getCertificate(alias)?.publicKey
        return if (privateKey != null && publicKey != null) {
            KeyPair(publicKey, privateKey)
        } else {
            null
        }
    }

    private fun createAndroidKeyStore(): KeyStore {
        val keyStore = KeyStore.getInstance("AndroidKeyStore")
        keyStore.load(null)
        return keyStore
    }

}
当我切换到使用私钥展开时,如下所示

unwrapCipher.init(Cipher.UNWRAP_MODE, masterKey?.private)
val encryptedKeyData = Base64.decode(encryptionKey, Base64.DEFAULT)
val symmetricKey = unwrapCipher.unwrap(encryptedKeyData, ALGORITHM_AES, Cipher.SECRET_KEY) as SecretKey
我得到了以下线索

stackTrace: java.security.InvalidKeyException: Failed to unwrap key
        at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineUnwrap(AndroidKeyStoreCipherSpiBase.java:682)
        at javax.crypto.Cipher.unwrap(Cipher.java:2440)
        at com.libencryption.data.EncryptionService.encryptWithSymmetricKey(EncryptionService.kt:58)
        at com.libencryption.data.EncryptionService.encrypt(EncryptionService.kt:37)

我假设这是由于我将UserAuthenticationRequired设置为true导致的,因为当我将其设置为false时,所有加密都很好。但是,正如您从stackstrace中看到的,没有记录异常。有没有其他原因导致setUserAuthenticationRequired为true时失败?

在公钥/私钥加密中,加密是用公钥完成的,解密是用私钥执行的。不要试图解释异常所说的话,而是发布整个异常堆栈跟踪,并告诉我们代码中的哪一行触发了异常。更好的是,还包括实际涉及的关键点。我们的目标是有一个完整的例子来说明这个问题。我的错误。那么,还有其他选择吗?除了:-用户使用对称密钥授权每个加密-手动分离数据并使用公共非对称密钥加密其部分key@PresidentJamesK.Polk. 我添加了stacktrace,并在引发异常的地方添加了注释。我不太清楚你说的包括实际钥匙是什么意思。我的意思是,对不起。在函数“EncryptWithSymmetyKey”中,您试图使用以下代码行打开(使用RSA加密的)对称密钥:“unwrapipher.init(Cipher.unwrap_模式,masterKey?.public)”。您正在尝试使用公钥展开=解密-尝试更改为私钥。
stackTrace: java.security.InvalidKeyException: Failed to unwrap key
        at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineUnwrap(AndroidKeyStoreCipherSpiBase.java:682)
        at javax.crypto.Cipher.unwrap(Cipher.java:2440)
        at com.libencryption.data.EncryptionService.encryptWithSymmetricKey(EncryptionService.kt:58)
        at com.libencryption.data.EncryptionService.encrypt(EncryptionService.kt:37)