我有一个运行良好的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;
返回:
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("\0", 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("\0", 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()));