使用硬编码密钥在Java中模拟实现PHP的openssl_decrypt功能
解决方法
不一致根因
- PHP 使用
aes-256-cbc算法时要求密钥长度为32字节,当传入的硬编码密钥不足32位时,会自动在末尾填充ASCII 0(即\0)直到长度满足要求 - 你当前的Java代码仅传入了16字节的密钥,
SecretKeySpec会默认按AES-128处理,两边算法密钥长度不匹配,导致加密结果不一致
修正后的Java代码
无需修改原有PHP代码,只需要在Java侧对齐PHP的密钥填充逻辑即可:
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class AesTest { public static void main(String[] args) throws Exception { // 原始硬编码密钥,和PHP侧保持一致 String rawKey = "1234567899999999"; // 对齐PHP逻辑:用\0补全密钥到32字节 byte[] keyBytes = new byte[32]; byte[] rawKeyBytes = rawKey.getBytes(StandardCharsets.UTF_8); System.arraycopy(rawKeyBytes, 0, keyBytes, 0, rawKeyBytes.length); // IV和PHP侧保持一致,16字节无需额外处理 byte[] ivBytes = "0123456789999999".getBytes(StandardCharsets.UTF_8); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(ivBytes)); byte[] encryptBytes = cipher.doFinal("123::secret".getBytes(StandardCharsets.UTF_8)); String encryptResult = Base64.getEncoder().encodeToString(encryptBytes); // 输出结果为 VZq5nLyJaAzajWQqMMLgmQ==,和PHP输出完全一致 System.out.println(encryptResult); } }
注意事项
如果实际业务中明文、密钥、IV包含非ASCII字符,必须显式指定两边的字符编码为同一标准(比如统一用UTF-8),避免不同环境默认编码差异导致加密解密失败。
内容的提问来源于stack exchange,提问作者Ed Loktseu
相关产品推荐
相关产品推荐

