Kotlin中AES解密触发BadPaddingException问题求助
解决AES/CBC/PKCS5Padding的BadPaddingException问题
问题根源
你的代码中加密与解密使用的密钥不一致,这是引发填充错误的核心原因:
- 在
encrypto函数里,你对密码生成的SHA256结果重复执行了一次SHA256哈希,用二次哈希后的字节作为加密密钥; - 但
decrypto函数中仅对密码做了一次SHA256哈希,直接用这个结果作为解密密钥。
两者密钥完全不同,自然无法正确解密,最终触发BadPaddingException。
另外,getIV函数的实现不符合安全规范:你用AES密钥生成器的密钥字节填充IV,而IV应该是完全随机的字节数组,而非从密钥派生。
修正后的完整代码
import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec import java.security.MessageDigest import java.security.SecureRandom data class EncryptoBinary(var iv: ByteArray, var body: ByteArray) // 正确生成随机IV fun getIV(): ByteArray { val iv = ByteArray(16) SecureRandom().nextBytes(iv) return iv } fun getSharedKeySHA256(password: String): ByteArray { val sha256Digest = MessageDigest.getInstance("SHA-256") return sha256Digest.digest(password.toByteArray(Charsets.UTF_8)) } val CipherMode = "AES/CBC/PKCS5Padding" fun encrypto(plainText: String, password: String): EncryptoBinary { val ivBinary = getIV() val ivSpec = IvParameterSpec(ivBinary) val sharedKey = getSharedKeySHA256(password) // 移除重复的SHA256哈希,保证加密密钥与解密密钥一致 val keySpec = SecretKeySpec(sharedKey, "AES") val cipher = Cipher.getInstance(CipherMode) cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec) val plainBinary = plainText.toByteArray(Charsets.UTF_8) val encryptedBinary = cipher.doFinal(plainBinary) return EncryptoBinary(ivBinary, encryptedBinary) } fun decrypto(enc: EncryptoBinary, password: String): ByteArray { val cipher = Cipher.getInstance(CipherMode) val secretKeySpec = SecretKeySpec(getSharedKeySHA256(password), "AES") val ivParameterSpec = IvParameterSpec(enc.iv) cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec) return cipher.doFinal(enc.body) } fun main() { val password = "0123456789012345" val plainText = "HOGEHOGEPIYOPIYOHOGEHOGEPIYOPIYOHOGEHOGEPIYOPIYOHOGEHOGEPIYOPIYO" val enc = encrypto(plainText, password) val dec = decrypto(enc, password) println(String(dec)) // 验证解密结果与原明文一致 }
关键修正点说明
- 密钥一致性:删除加密函数中多余的SHA256哈希步骤,确保加密和解密使用完全相同的密钥。
- IV生成规范:改用
SecureRandom生成随机IV,符合AES-CBC模式的安全要求,避免从密钥派生IV的风险。 - 代码清晰度:加密后直接返回生成的IV(与
cipher.iv结果一致),逻辑更直观。
内容的提问来源于stack exchange,提问作者ikuo xy
相关产品推荐
相关产品推荐

