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

问题描述

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

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
    }

}
stackTrace: java.security.InvalidKeyException: javax.crypto.BadPaddingException: 
error:0400006b:RSA routines:OPENSSL_internal:BLOCK_TYPE_IS_NOT_01
        at com.android.org.conscrypt.OpenSSLCipherRSA.engineUnwrap(OpenSSLCipherRSA.java:373)
        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)

当我像下面建议的那样使用私钥切换时

unwrapCipher.init(Cipher.UNWRAP_MODE,masterKey?.private)
val encryptedKeyData = Base64.decode(encryptionKey,Base64.DEFAULT)
val symmetricKey = unwrapCipher.unwrap(encryptedKeyData,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)
我认为的

是由于将setUserAuthenticationRequired设置为true引起的,因为当我将其设置为false时,所有加密都可以。但是,正如从stackstrace中看到的那样,未记录该异常。还有其他原因导致失败的原因,例如setUserAuthenticationRequired为true吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...