我在Kotlin中创建了这两个扩展来加密/解密字符串:
fun String.encrypt(seed : String): String {
val keyGenerator = KeyGenerator.getInstance("AES")
val secureRandom = SecureRandom.getInstance("SHA1PRNG")
secureRandom.setSeed(seed.toByteArray())
keyGenerator.init(128, secureRandom)
val skey = keyGenerator.generateKey()
val rawKey : ByteArray = skey.encoded
val skeySpec = SecretKeySpec(rawKey, "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, skeySpec)
val byteArray = cipher.doFinal(this.toByteArray())
return byteArray.toString()
}
fun String.decrypt(seed : String): String {
val keyGenerator = KeyGenerator.getInstance("AES")
val secureRandom = SecureRandom.getInstance("SHA1PRNG")
secureRandom.setSeed(seed.toByteArray())
keyGenerator.init(128, secureRandom)
val skey = keyGenerator.generateKey()
val rawKey : ByteArray = skey.encoded
val skeySpec = SecretKeySpec(rawKey, "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, skeySpec)
val byteArray = cipher.doFinal(this.toByteArray())
return byteArray.toString()
}
由于某种原因,我得到以下异常:
javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
我做错了什么?
2 回答
要对密文进行编码,请使用base 64或hexadecimals . Java API包含Base64类,因此您可能最好使用它 .
byte[]#toString
没有做你期望它做的事情;它只返回字节数组引用的表示,而不是字节数组的内容 .除此之外:
不要使用SecureRandom派生密钥,尝试查找PBKDF2;
明确使用一种操作模式,如
"AES/GCM/NoPadding"
;如果您决定使用CBC(通常不安全),
使用独特的IV和随机IV;
如果没有明确选择邮件的字符编码,请不要使用
toByteArray
.按照Maarten Bodews指南,我将问题解决为: