首页 > 解决方案 > 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)

标签: androidencryptionaesaes-gcm

解决方案


推荐阅读