我的项目中要求下载和存储加密的文件。经过研究,我发现GCM的AES符合我的要求。我做了一个演示应用程序作为概念证明。当我尝试加密和解密字符串时,我的代码工作正常。我相信加密是有效的,因为我得到的文件大小与原始文件相同。问题是当我解密加密文件时,它显示为
的异常javax.crypto.AEADBadTagException:错误:1e000065:密码 函数:OPENSSL_internal:BAD_DECRYPT
这是我的代码
加密
fun encrypt(data : ByteArray, iv : ByteArray, secretKey : SecretKey) : ByteArray{
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val parameterSpec = GCMParameterSpec(128, iv)
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec)
val encrypted = cipher.doFinal(data)
val byteBuffer = ByteBuffer.allocate(4 + iv.size + encrypted.size)
byteBuffer.putInt(iv.size)
byteBuffer.put(iv)
byteBuffer.put(encrypted)
val cipherMessage = byteBuffer.array()
return cipherMessage
}
解密
fun decrypt(cipherMessage : ByteArray, key : SecretKey) : ByteArray{
val byteBuffer = ByteBuffer.wrap(cipherMessage)
val ivLength = byteBuffer.int
if (ivLength < 12 || ivLength >= 16) {
throw IllegalArgumentException("invalid iv length")
}
val iv = ByteArray(ivLength)
byteBuffer.get(iv)
val cipherText = ByteArray(byteBuffer.remaining())
byteBuffer.get(cipherText)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, key, GCMParameterSpec(128, iv))
val plainText = cipher.doFinal(cipherText)
return plainText
}
密钥生成
val secureRandom = SecureRandom()
val key = ByteArray(16)
secureRandom.nextBytes(key)
val secretKey = SecretKeySpec(key, "AES")
val iv = ByteArray(12)
secureRandom.nextBytes(iv)
为了简化起见,我使用以下代码将文件读写到磁盘中。
读取,加密和写入
do {
count = input.read(data)
if (count == -1)
break
total += count
output.write(encrypt(data, iv, secretKey), 0, count)
} while (true)
读取,解密和写入
do {
count = input2.read(data)
Log.e("Worker", "Count:$count")
if (count == -1)
break
total += count
output2.write(decrypt(data, secretKey), 0, count)
} while (true)