在 Java 中替代 PHP 加密

Alternative to PHP Encryption in Java

我有一个工作正常的 PHP,我想复制它并想使用 java 来完成它。 我的 PHP 代码使用 MCRYPT_RIJNDAEL_256 :

 $iv = "42309842389462374623784692423642";
   $key = "asfuyjkdhfabcdef";
   $text = "0007";    

  $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
  $padding = $block - (strlen($text) % $block);
  $text .= str_repeat(chr($padding), $padding);
  $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
  $crypttext64=base64_encode($crypttext);

  echo $crypttext64;

哪个returns:KdL2lWUGqy+UqLxbe9VTS6OCgvnJFn1jtMCgkj1434A=

但是在使用 java 加密时:

  byte[] sessionKey = "asfuyjkdhfabcdef".getBytes(Charset.forName("ASCII"));

  byte[] iv = "42309842389462374623784692423642".getBytes(Charset.forName("ASCII"));

            String plaintext="0007";

            String data = new String(new char[28]).replace("[=13=]", Character.toString ((char) 28));

            String newdata = plaintext+data;
            newdata = newdata.substring(0,32);
            byte [] dataBytes = newdata.getBytes(Charset.forName("ASCII"));
            System.out.println(dataBytes);

            PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
                new CBCBlockCipher(new RijndaelEngine(256)),new PKCS7Padding());



            cipher.init(true, new ParametersWithIV(new KeyParameter(sessionKey), iv));


            byte[] encrypted  = new byte[cipher.getOutputSize(dataBytes.length)];

            int oLen = cipher.processBytes(dataBytes, 0, dataBytes.length, encrypted, 0);
            cipher.doFinal(encrypted, oLen);   
             String s = new String(encrypted);
            System.out.println(Base64.getEncoder().encodeToString(s.getBytes()));

我的输出低于:

KdL2lWUGqy+UqLxbe9VTS6OCgvnJFn1jtMCgkj1434DMpLehN7ve0AhnMOQtT1fLcZIUfM9rF/iVOKj6UtgwyA==

两者的输出不同。 请建议方法,以便我也可以在 JAVA 中获得相同的输出。

您似乎尝试执行两次填充:

String data = new String(new char[28]).replace("[=10=]", Character.toString ((char) 28));

String newdata = plaintext+data;
newdata = newdata.substring(0,32);
byte [] dataBytes = newdata.getBytes(Charset.forName("ASCII"));
System.out.println(dataBytes);

似乎是执行 PKCS#7 填充的书面尝试,您已经在您的代码中这样做了 (new PKCS7Padding())。

只需将其替换为:

plaintext.getBytes(StandardCharsets.US_ASCII)

如您所见,PHP 和 Java 中 base 64 的第一部分是相同的。请注意 PHP 不包含 PKCS#7 填充,这就是使用 str_repeat.

编码的原因

而且encrypted数组应该直接放入encodeToString方法中,先转为String再转回byte[],只能松数据。所以在下面的代码中去掉s

String s = new String(encrypted);
System.out.println(Base64.getEncoder().encodeToString(s.getBytes()));