PHP Java 中的 AES-Rijndael 128 加密

AES-Rijndael 128 encryption in Java from PHP

我有一段代码在PHP

    function encrypt($data){
$data = "{\"userId\":11,\"email\":\"ssss.bansa11l1989@gmail.com\",\"firstName\":\"Ankit\",\"lastName\":\"Bansal\",\"displayName\":\"banank1989\",\"visitorId\":\"1222222234455\"}";

            $td = mcrypt_module_open('rijndael-128', '', 'cbc', $this->iv);

            mcrypt_generic_init($td, $this->key, $this->iv);
            $encrypted = mcrypt_generic($td, $data);

            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);

            return bin2hex($encrypted);
        }

现在,当我尝试在 java 中编写相同的代码时,它给出了不同的输出

public String encrypt(String value) {
        try {

            value="{\"userId\":11,\"email\":\"ssss.bansa11l1989@gmail.com\",\"firstName\":\"Ankit\",\"lastName\":\"Bansal\",\"displayName\":\"banank1989\",\"visitorId\":\"1222222234455\"}";
            String initVector = "fedcba9876111111";
            String key = "012345678911111";
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes());
            return new String(Base64.encodeBase64(encrypted));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

现在的问题是,对于相同的提供,两个代码都给我不同的结果 JSON。

我无法更改 PHP 代码,所以我必须更改 JAVA 代码。

您可以将您的代码的结果 运行 与 http://www.maidoupig.cn/encode/aes

的结果进行比较

Java 和 PHP 代码不同:

  • 在PHP-代码Zero-Byte-Padding is used, because this is mcrypt's default padding (see )。相反,在 Java 代码中使用 PKCS7-Padding(在 Java 中也称为 PKCS5)。要在 Java 代码中使用零字节填充,首先,通过将 AES/CBC/PKCS5PADDING 替换为 AES/CBC/NoPadding 来停用 PKCS7 填充。其次,手动实施零字节填充,即向消息的字节序列添加 n 0 值(使用 0 <= n < 16),直到长度对应于块大小(16 字节)的整数倍。
  • 在 PHP 代码中,加密数据以十六进制字符串形式返回。相反,在 Java 代码中,加密数据以 Base64 编码返回。要更改后者,您必须将加密数据转换为十六进制字符串,请参见例如How to convert a byte array to a hex string in Java?.

通过这些更改,如果使用相同的密钥和相同的 IV,Java- 和 PHP- 代码将产生相同的结果(顺便说一下 Java- 中的密钥code 的长度为 15 字节,结果为 InvalidKeyException (Invalid AES key length: 15 bytes)).

备注mcrypt is deprecated and Zero-Byte-Padding isn't reliable。如果您可以选择更改填充,PKCS7 更可取。