我尝试以最简单的方式对字符串进行密码和解密,但它不起作用...
经过几个小时的研究,我试着在这里发布我的问题。 我已经将问题减少到最低限度,但它仍然无法正常工作,我也不了解错误。
这是我的代码:
class MainActivity : AppCompatActivity()
{
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val password = "passwordpassword"
val plainText = "tototiti123"
val encryptText = encrypt(plainText, password)
text.text = decrypt(encryptText, password)
}
private fun encrypt(plainText: String, password: String): String
{
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val key = SecretKeySpec(password.toByteArray(charset("UTF-8")), "AES")
cipher.init(Cipher.ENCRYPT_MODE, key)
return String(cipher.doFinal(plainText.toByteArray(charset("UTF-8"))))
}
private fun decrypt(encrypted: String, password: String): String
{
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val key = SecretKeySpec(password.toByteArray(charset("UTF-8")), "AES")
val r = SecureRandom()
r.setSeed(r.generateSeed(16))
val byteIV = ByteArray(16)
r.nextBytes(byteIV)
cipher.init(Cipher.DECRYPT_MODE, key, IvParameterSpec(byteIV))
return String(cipher.doFinal(encrypted.toByteArray(charset("UTF-8"))))
}
}
这是我的错误:
AndroidRuntime: FATAL EXCEPTION: main
Process: com.cryptapp, PID: 17710
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cryptapp/com.cryptapp.MainActivity}: javax.crypto.IllegalBlockSizeException: error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: javax.crypto.IllegalBlockSizeException: error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
at com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER.doFinalInternal(OpenSSLCipher.java:570)
at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:351)
at javax.crypto.Cipher.doFinal(Cipher.java:1741)
at com.cryptapp.MainActivity.decrypt(MainActivity.kt:47)
at com.cryptapp.MainActivity.onCreate(MainActivity.kt:23)
at android.app.Activity.performCreate(Activity.java:7009)
at android.app.Activity.performCreate(Activity.java:7000)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
有谁知道我的代码出了什么问题?
先谢谢你。
答案 0 :(得分:2)
当您从String
返回的字节中创建Cipher.doFinal
时,会出现问题,这些字节不能用于直接创建String
。
实际上,如果你打印2字节数组就可以得到这个:
Cipher.doFinal(..) -> [-124, -59, 116, -79, 27, 67, -75, 5, -6, -58, 9, -104, 16, 65, -9, -95]
encryptText.toByteArray() -> [-17, -65, -67, -17, -65, -67, 116, -17, -65, -67, 27, 67, -17, -65, -67, 5, -17, -65, -67, -17, -65, -67, 9, -17, -65, -67, 16, 65, -17, -65, -67, -17, -65, -67]
您应该直接保存字节数组或将其转换为其他内容,如Base64。
此外,在解密Cipher
中,您随机生成初始化向量,而在加密Cipher
中则不然,因此您永远无法解密加密的内容。
一个完整的例子:
import java.security.SecureRandom
import java.util.*
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
fun main(args: Array<String>) {
val password = "passwordpassword"
val plainText = "tototiti123"
val r = SecureRandom()
r.setSeed(r.generateSeed(16))
val byteIV = ByteArray(16)
r.nextBytes(byteIV)
val encryptText = encrypt(plainText, password, byteIV)
val bytes = Base64.getDecoder().decode(encryptText)
println(decrypt(bytes, password, byteIV))
}
fun encrypt(plainText: String, password: String, byteIV: ByteArray): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val key = SecretKeySpec(password.toByteArray(charset("UTF-8")), "AES")
cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(byteIV))
val bytes = cipher.doFinal(plainText.toByteArray(charset("UTF-8")))
return Base64.getEncoder().encodeToString(bytes)
}
fun decrypt(bytes: ByteArray, password: String, byteIV: ByteArray): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val key = SecretKeySpec(password.toByteArray(charset("UTF-8")), "AES")
cipher.init(Cipher.DECRYPT_MODE, key, IvParameterSpec(byteIV))
return String(cipher.doFinal(bytes))
}
答案 1 :(得分:0)
您收到此错误是因为输入数据不是块大小的倍数(AES为16字节)。
这可能是Cipher: What is the reason for IllegalBlockSizeException?
的副本