Java解密PHP生成的AES/GCM/128加密内容报错如何解决
问题原因分析
你的Java解密代码存在3处核心逻辑错误,与PHP加密逻辑不匹配:
- 密钥派生逻辑完全错误:PHP侧直接将传入的
secret十六进制字符串转为原始二进制密钥,没有经过PBKDF2算法派生,原代码中的generateSecretKeyFromPassword方法是多余的错误逻辑。 - IV长度配置错误:AES-128-GCM标准IV长度为12字节,你传入了16字节参数,导致IV提取错误。
- 未正确匹配GCM标签结构:PHP加密输出的结构为
12字节IV + 密文 + 16字节GCM标签,原代码没有对应处理该结构。
正确Java解密实现代码
import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; public class MyTest { public static void main(String[] args) throws Exception { String secret = "544553544B4559313233343536"; String encryptStr = "Fun3yZTPcHsxBpft+jBZDe2NjGNAs8xUHY21eZswZE4iLKYdBsyER7RwVfFvuQ=="; String decryptString = decrypt(encryptStr, secret); System.out.println("decryptString: " + decryptString); } private static String decrypt(String data, String secretHex) throws Exception { // 1. base64解码加密内容 byte[] encryptedBytes = Base64.getDecoder().decode(data); // 2. 提取前12字节作为IV byte[] iv = new byte[12]; System.arraycopy(encryptedBytes, 0, iv, 0, 12); // 3. 把十六进制密钥转为二进制字节数组 byte[] secretKey = hexStringToByteArray(secretHex); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "AES"); // 4. GCM参数配置,标签长度为128位(16字节) GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv); Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec); // 5. 解密:从第12字节开始读取剩余内容(密文+标签) byte[] plainBytes = cipher.doFinal(encryptedBytes, 12, encryptedBytes.length - 12); return new String(plainBytes); } // 十六进制字符串转二进制字节数组工具方法 private static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } }
运行结果
decryptString: Test text.{123456}
内容的提问来源于stack exchange,提问作者job
相关产品推荐
相关产品推荐

