android - android/java 和 web/javascript 之间的 AES-GCM 加密兼容性
问题描述
问题定义:我需要能够在Android平台和Web上互换加密和解密数据。现在,我的解决方案是专门的工作平台,即网络加密数据只能在网络上解密,而在 android 上失败AEADBadTagExcepton:mac check in GCM failed
,同样的 android 加密数据无法在网络上解密。我花了很多时间,但还没有找到解决方案。
AES-GCM 在安卓和网络上会有所不同吗?尽管密钥和文本相同,但 android 和 web 的加密输出不同我使用AES-GCM
算法进行加密,另请参阅下面的代码
安卓代码
fun encryptAES(textToEncrypt: String, secretKey: ByteArray?, iv: ByteArray): String? {
return try {
val secretKeySpec = SecretKeySpec(secretKey, 0, secretKey?.size!!, "AES")
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val parameterSpec = GCMParameterSpec(128, iv) //128 bit auth tag length
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, parameterSpec)
val cipherText = cipher.doFinal(textToEncrypt.toByteArray(Charsets.UTF_8))
encodeToBase64String(cipherText)
} catch (e: Exception) {
e.printStackTrace();
""
}
}
fun decryptAES(cipherString: String?, secretKeyBytes: ByteArray?, iv: ByteArray?): String? {
return try {
val secretKeySpec = SecretKeySpec(secretKeyBytes, 0, secretKeyBytes?.size!!, "AES")
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val cipherMessage = decodeBase64(cipherString)
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, GCMParameterSpec(128, iv)) //128 is tag length which is also same on web side
val plainTextByteArray = cipher.doFinal(cipherMessage)
String(plainTextByteArray, Charsets.UTF_8)
} catch (e: Exception) {
""
}
}
使用 SubtleCrypto API 的网页代码
crypto.subtle.encrypt({name: "aes-gcm", iv: iv}, secretKey, plainText)
crypto.subtle.decrypt({name: "aes-gcm", iv: iv}, secretKey, cipherText)
解决方案
推荐阅读
- google-app-engine - 无法使用私有 IP 地址连接到 GCP CloudSQL(CORS 错误预检缺少允许源标头)
- reactjs - Inotify watchers + React + Typescript + AWS ECS Fargate 问题
- python - 如何根据条件删除行?
- sql - 如何获得平均每天的操作次数
- mysql - 条件的 SQL 查询优化
- python - 如何报告熊猫数据框的所有数据上存在错误字符?
- c# - 如何通过依赖注入使用 Azure 事件中心处理器
- sockets - 如何始终读取缓冲区并连接到 esp8266 wifi 和读取线
- python - MinHash LSH - 如何在 PySpark 中计算输出列?
- go - 使用内部函数测试 Golang http 处理程序