Java Kotlin AES BAD_解密

Java Kotlin AES BAD_解密,java,android,kotlin,encryption,aes-gcm,Java,Android,Kotlin,Encryption,Aes Gcm,我正在尝试加密和解密Kotlin中的字符串/文件。 我正在使用下面的Java教程来实现这一点 当我试图运行它时,它抛出一个错误“…Cipher functions:OPENSSL\u internal:BAD\u DECRYPT…”当在DECRYPT函数中执行doFinal时,它会出错 我已经试了好几个小时了,但是运气不好 这是代码 private const val ENCRYPT_ALGO = "AES/GCM/NoPadding" private con

我正在尝试加密和解密Kotlin中的字符串/文件。 我正在使用下面的Java教程来实现这一点

当我试图运行它时,它抛出一个错误“…Cipher functions:OPENSSL\u internal:BAD\u DECRYPT…”当在DECRYPT函数中执行doFinal时,它会出错

我已经试了好几个小时了,但是运气不好

这是代码

   private const val ENCRYPT_ALGO = "AES/GCM/NoPadding"

    private const val TAG_LENGTH_BIT = 128 

    private const val IV_LENGTH_BYTE = 12
    private const val SALT_LENGTH_BYTE = 16
    
    fun getRandomNonce(): ByteArray {
        val nonce = ByteArray(16)
        SecureRandom().nextBytes(nonce)
        return nonce
    }
    
    fun getAESKeyFromPassword(password: CharArray?, salt: ByteArray?): SecretKey {
        val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
        val spec: KeySpec = PBEKeySpec(password, salt, 65536, 256)
        return SecretKeySpec(factory.generateSecret(spec).encoded, "AES")
    }

    
    fun encryptFile(pText: ByteArray, password: String): String {
        
        val salt: ByteArray = getRandomNonce()
        val iv: ByteArray = getRandomNonce()
        
        val aesKeyFromPassword: SecretKey = getAESKeyFromPassword(password.toCharArray(), salt)
        val cipher = Cipher.getInstance(ENCRYPT_ALGO)
        
        cipher.init(Cipher.ENCRYPT_MODE, aesKeyFromPassword, GCMParameterSpec(TAG_LENGTH_BIT, iv))
        val cipherText = cipher.doFinal(pText)
        
        val cipherTextWithIvSalt: ByteArray =
            ByteBuffer.allocate(iv.size + salt.size + cipherText.size)
                .put(iv)
                .put(salt)
                .put(cipherText)
                .array()
        
        return Base64.getEncoder().encodeToString(cipherTextWithIvSalt)
    }


    fun decryptFile(cText: String, password: String): String {
        val decode: ByteArray = Base64.getDecoder().decode(cText.toByteArray())
        
        val bb: ByteBuffer = ByteBuffer.wrap(decode)
        val iv = ByteArray(IV_LENGTH_BYTE)
        bb.get(iv)
        val salt = ByteArray(SALT_LENGTH_BYTE)
        bb.get(salt)
        val cipherText = ByteArray(bb.remaining())
        bb.get(cipherText)
        
        val aesKeyFromPassword: SecretKey = getAESKeyFromPassword(password.toCharArray(), salt)
        val cipher = Cipher.getInstance(ENCRYPT_ALGO)
        cipher.init(Cipher.DECRYPT_MODE, aesKeyFromPassword, GCMParameterSpec(TAG_LENGTH_BIT, iv))
        val plainText = cipher.doFinal(cipherText)
        return String(plainText, StandardCharsets.UTF_8)
    }

我哪里出错了?

错误是在
encryptFile()
中,salt和IV是使用
getrandomonce()
方法确定的,该方法返回一个随机的16字节数组。但在
decryptFile()
中,假设IV的长度为
IV_length_BYTE
(12字节),salt的长度为
salt_length_BYTE
(16字节)。即,两种实施方式在IV长度方面不一致。请注意,对于GCM,IV的长度必须确实为12字节

一种可能的修复方法是修改
getrandomonce()
方法,如下所示:

fun getRandomNonce(size: Int): ByteArray {
    val nonce = ByteArray(size)
    SecureRandom().nextBytes(nonce)
    return nonce
}
以及
encryptFile()
中的以下更改:


通过这些更改,代码在我的机器上成功执行。

decode(cText.toByteArray())
应该是
decode(cText)
@kelalalaka我已经尝试过了,这对解码到ByteArray是有意义的。但是没有运气。这给了我同样的错误。
val salt: ByteArray = getRandomNonce(SALT_LENGTH_BYTE)
val iv: ByteArray = getRandomNonce(IV_LENGTH_BYTE)