PHP解密Kotlin端AES加密字符串遇空结果问题求助
Kotlin AES加密后PHP解密失败的解决方法
问题根源分析
你的代码存在三个核心问题,导致解密结果为空:
- IV不匹配:CBC模式加密和解密必须使用完全相同的初始化向量(IV),但你Kotlin代码中未保存加密时自动生成的IV,PHP端却随机生成新IV,两者完全无法对应。
- 密钥处理不一致:Kotlin将密码通过SHA256哈希后作为AES密钥,PHP直接使用原密码字符串作为密钥,两端密钥完全不同。
- 加密数据传递错误:Kotlin返回的
ByteArray是二进制数据,直接通过GET传递会因编码问题丢失信息,必须转成Base64或十六进制字符串才能安全传输。
修正后的Kotlin加密代码
修改加密逻辑,保存加密时生成的IV,并将IV与密文拼接后转成Base64字符串(适配HTTP传输):
private fun encrypt(context: Context, strToEncrypt: String, encryptKey: String): String { val plainText = strToEncrypt.toByteArray(Charsets.UTF_8) val key = generateKey(encryptKey) val cipher = Cipher.getInstance("AES_256/CBC/PKCS5PADDING") // 初始化加密模式,自动生成IV cipher.init(Cipher.ENCRYPT_MODE, key) val iv = cipher.iv // 获取加密时生成的IV val cipherText = cipher.doFinal(plainText) // 拼接IV和密文,转Base64后返回 val combinedData = iv + cipherText return Base64.encodeToString(combinedData, Base64.DEFAULT) } private fun generateKey(password: String): SecretKeySpec { val digest: MessageDigest = MessageDigest.getInstance("SHA-256") val bytes = password.toByteArray(Charsets.UTF_8) // 明确指定UTF-8,避免平台编码差异 digest.update(bytes, 0, bytes.size) val key = digest.digest() return SecretKeySpec(key, "AES") }
调用后会返回一个包含IV和密文的Base64字符串,可直接通过GET参数传递。
修正后的PHP解密代码
对应解析Base64字符串分离IV和密文,按相同逻辑生成密钥后执行解密:
function decryptString($encryptedBase64, $cipher, $password) { // 解码Base64得到二进制数据 $combinedData = base64_decode($encryptedBase64); // AES-256-CBC的IV固定为16字节 $ivSize = openssl_cipher_iv_length($cipher); // 分离IV和密文:前16字节是IV,剩余部分是密文 $iv = substr($combinedData, 0, $ivSize); $cipherText = substr($combinedData, $ivSize); // 对密码做SHA256哈希,生成与Kotlin端一致的密钥(true返回二进制结果) $key = hash('sha256', $password, true); // 执行解密,OPENSSL_RAW_DATA指定输入输出为二进制数据 $decryptedText = openssl_decrypt($cipherText, $cipher, $key, OPENSSL_RAW_DATA, $iv); return $decryptedText; } if (isset($_GET["encrypted_text"])) { $cipher = "aes-256-cbc"; $password = "password"; echo decryptString($_GET["encrypted_text"], $cipher, $password); }
关键注意事项
- IV的必要性:CBC模式下IV不需要保密,但必须随密文一起传递,加密和解密必须使用同一IV。
- 密钥一致性:两端必须用完全相同的逻辑生成密钥,这里均对原始密码做SHA256哈希(PHP需指定
hash函数返回二进制结果)。 - 数据编码:二进制密文必须转成Base64或十六进制字符串后再通过HTTP传输,避免二进制数据在传输过程中损坏。
内容的提问来源于stack exchange,提问作者user2959923
相关产品推荐
相关产品推荐

