我对 Kotlin AES GCM 加密有疑问。解密时,密钥、iv、标签和数据来自第三方 API,在他们的 JavaScript 文档中,该过程类似于以下代码:
for (var i = 0; i < validations.length; i++) {
var decipher = forge.cipher.createDecipher("AES-GCM", sessionKey);
decipher.start({
iv: atob(validations[i].iv),
tag: atob(validations[i].tag),
});
decipher.update(forge.util.createBuffer(atob(validations[i].data)));
var pass = decipher.finish();
if (pass) {
dec_validations.push({
data: btoa(decipher.output.data),
id: validations[i].id,
});
}
}
我的 Kotlin 代码是这样的:
fun main() {
val myTestKey = "22+uMvw39JLTXeBJweORNRQPeVneGP0+oQgvwmjSx4Y="
val iv = "+7/pEeTMDH8uyShG"
val tag = "3sSY6JEEY8EdXMmrnhgN3Q=="
val cipherText = "jzgiE5bec+ty0xI3zhsXZVbCuUwSttOBpuH2Ts0R/CLVh9Vf4rw2HM7ZRWizXcQ1SElurXdNNFRyfXMF8N/WUjjPgaUAV9dvtB8wfDqkq5rsbvpUIi8OAVXvAa/rwhMZgfTcIOUbB2q3A+tft3T+K4aBSOTl1a8btmjMmlZ+lFYIXWLBSu0L9As6gAkSUkCWOQMs7Up9guOnP9r6E/lhO1gQnuPkebiKjJWkVYM+Ezwgnne0b4P6dD59aPc03eqxmMRdxk5/SSbPLysj2pHprsD01zH401KsID+Ny5sJDS1gvXz8eegTySriKEIpMn8nUkK5yKru4aEgGFcz0amSlK1dmqmAdL6ZOPcT3EAcobY="
val decodedKey = Base64.getDecoder().decode(myTestKey)
val sessionKeySpec: Key = SecretKeySpec(decodedKey, "AES")
val ivBytes = Base64.getDecoder().decode(iv)
val tagBytes = Base64.getDecoder().decode(tag)
val gcmSpec: AlgorithmParameterSpec = GCMParameterSpec(128, ivBytes)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, sessionKeySpec, gcmSpec)
val ciphertext = Base64.getDecoder().decode(cipherText)
val combined = ByteBuffer.allocate(ciphertext.size + tagBytes.size)
.put(ciphertext)
.put(tagBytes)
.array()
val plaintext = cipher.doFinal(combined)
println(String(plaintext))
}
我尝试过的:
cipher.updateAAD(tagBytes)
。您的数据有些混乱,密文似乎已经包含附加到末尾的 AES-GCM 身份验证标签。我不确定变量
tag
包含什么,但如果我将最后一行更改为 val plaintext = cipher.doFinal(ciphertext)
(即排除 tagBytes
),那么解密就会成功。