尝试在Android中解密时出现AES BadTag异常

问题描述

我正在尝试使用AES加密来加密一个简单的字符串。 目前,我正在使用@media (min-width: 768px) .col-md-9 {flex: 0 0 75%;max-width: 75%;} 生成密钥,并且正在使用KeyGenerator

生成16字节的随机IV。

问题是,当我运行此代码时:

Secure Random

我得到一个运行时执行语句: @RequiresApi(Build.VERSION_CODES.M) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val random = SecureRandom() val iv = ByteArray(12) random.nextBytes(iv) aesKeystoreAESWrapper = AES_WRAPPER() aesKeystoreAESWrapper.createSymmetricKey() val teste = aesKeystoreAESWrapper.encrypt("OLA MALTA",iv) val result = aesKeystoreAESWrapper.decrypt(teste,iv) ola.text = result }

我不知道问题出在哪里,我尝试在多个网站中搜索,但找不到遮阳篷。

这是我的AES代码

javax.crypto.AEADBadTagException

更新,LOGCAT:

class AES_WRAPPER {

    fun ByteArray.fromBytetoString() = String(this,Charsets.UTF_8)
    companion object{
        const val AES_nopAD_TRANS = "AES/GCM/nopadding" //Format - ”Algorithm/Mode/Padding”
        const val ANDROID_KEYSTORE = "AndroidKeyStore"
        const val KEY_ALIAS = "Keyalaisasf"
    }

    private fun createKeyStore(): KeyStore {
        val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE)
        keyStore.load(null)
        return keyStore
    }

    @RequiresApi(23)
    fun createSymmetricKey() : SecretKey {
        try{
            val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,ANDROID_KEYSTORE)

            val keyGenParameterSpec = KeyGenParameterSpec.Builder(
                KEY_ALIAS,KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .setRandomizedEncryptionrequired(false)
                .build()
            keyGenerator.init(keyGenParameterSpec)
            return keyGenerator.generateKey()
        } catch (e: NoSuchAlgorithmException) {
            throw RuntimeException("Failed to create a symmetric key",e)
        } catch (e: NoSuchProviderException) {
            throw RuntimeException("Failed to create a symmetric key",e)
        } catch (e: InvalidAlgorithmParameterException) {
            throw RuntimeException("Failed to create a symmetric key",e)
        }
    }

    fun encrypt(data: String,initVector: ByteArray) : ByteArray{
        val iv = GCMParameterSpec(128,initVector)

        val cipher = Cipher.getInstance(AES_nopAD_TRANS)
        cipher.init(Cipher.ENCRYPT_MODE,getSymmetricKey(),iv)

        val encrypted = cipher.doFinal(data.toByteArray())

        return encrypted
    }

    fun decrypt(data: ByteArray,initVector: ByteArray) : String{
        val iv = GCMParameterSpec(128,initVector)

        val cipher = Cipher.getInstance(AES_nopAD_TRANS)
        cipher.init(Cipher.DECRYPT_MODE,iv)

        val decrypted = cipher.doFinal(data)

        return decrypted.fromBytetoString()
    }

    @SuppressLint("NewApi")
    fun getSymmetricKey(): SecretKey {
        /*val keysore = keyStore.getEntry(KEY_ALIAS,null) as KeyStore.SecretKeyEntry
        return keysore.secretKey*/

        val keyStore = createKeyStore()

        if(!isKeyExists(keyStore)){
            createSymmetricKey()
        }

        return keyStore.getKey(KEY_ALIAS,null) as SecretKey
    }

    fun isKeyExists(keyStore : KeyStore): Boolean {
        val aliases = keyStore.aliases()
        while (aliases.hasMoreElements()) {
            return (KEY_ALIAS == aliases.nextElement())
        }
        return false
    }

}

解决方法

此问题是由result = re.findall(r'"(id|code)":([0-9]+)',demo) print(result) # prints [('id','1'),('id','2'),'3'),'4'),'5'),'6'),'7'),'8'),'9'),('code','3')] 函数引起的,该函数应检查密钥存储区中是否包含isKeyExists()。但是,当前的实现仅针对KEY_ALIAS检查aliases.nextElement()找到的 first 别名,并返回此结果。因此,只有在密钥库中只有一个别名时,此功能才能可靠地工作。如果KEY_ALIAS在密钥库中但未被KEY_ALIAS首先发现,则别名不止一个会导致 false negative 结果。因此,将创建用于加密和解密的不同密钥,这会在解密期间引发 AEADBadTagException

如果在aliases.nextElement()中将while循环中的return语句替换为

,则可以解决问题。
if (KEY_ALIAS == aliases.nextElement()) return true

或者,如迈克尔评论中所建议,如果{{1}中的isKeyExists()keyStore.containsAlias(KEY_ALIAS)替换。