use*_*120 1 php java encryption aes
PHP功能:
$privateKey = "1234567812345678";
$iv = "1234567812345678";
$data = "Test string";
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv);
echo(base64_encode($encrypted));
Result: iz1qFlQJfs6Ycp+gcc2z4w==
Run Code Online (Sandbox Code Playgroud)
Java函数
public static String encrypt() throws Exception{
try{
String data = "Test string";
String key = "1234567812345678";
String iv = "1234567812345678";
javax.crypto.spec.SecretKeySpec keyspec = new javax.crypto.spec.SecretKeySpec(key.getBytes(), "AES");
javax.crypto.spec.IvParameterSpec ivspec = new javax.crypto.spec.IvParameterSpec(iv.getBytes());
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(data.getBytes());
return new sun.misc.BASE64Encoder().encode(encrypted);
}catch(Exception e){
return null;
}
Run Code Online (Sandbox Code Playgroud)
}
返回null.
请注意,我们不允许更改PHP代码.有人可以帮助我们在Java中获得相同的结果吗?非常感谢.
Qua*_*nic 10
你有什么事情,如果你并没有简单地吞掉可能更好的主意Exception是你的内部encrypt()程序.如果您的函数正在返回,null那么很明显发生了异常,您需要知道它是什么.
事实上,例外是:
javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:854)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:828)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at Encryption.encrypt(Encryption.java:20)
at Encryption.main(Encryption.java:6)
Run Code Online (Sandbox Code Playgroud)
当然,你的纯文本只有11个Java字符长,在你的默认编码中,它将是11个字节.
您需要检查PHP mcrypt_encrypt函数实际执行的操作.由于它的工作原理,它显然使用了一些填充方案.您需要找出它是哪一个并在Java代码中使用它.
好的 - 我查了手册页mcrypt_encrypt.它说:
将使用给定的密码和模式加密的数据.如果数据的大小不是
n * blocksize,则数据将被填充\0.
所以你需要在Java中复制它.这是一种方式:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Encryption
{
public static void main(String args[]) throws Exception {
System.out.println(encrypt());
}
public static String encrypt() throws Exception {
try {
String data = "Test string";
String key = "1234567812345678";
String iv = "1234567812345678";
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
int blockSize = cipher.getBlockSize();
// We need to pad with zeros to a multiple of the cipher block size,
// so first figure out what the size of the plaintext needs to be.
byte[] dataBytes = data.getBytes();
int plaintextLength = dataBytes.length;
int remainder = plaintextLength % blockSize;
if (remainder != 0) {
plaintextLength += (blockSize - remainder);
}
// In java, primitive arrays of integer types have all elements
// initialized to zero, so no need to explicitly zero any part of
// the array.
byte[] plaintext = new byte[plaintextLength];
// Copy our actual data into the beginning of the array. The
// rest of the array is implicitly zero-filled, as desired.
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return new sun.misc.BASE64Encoder().encode(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我跑步时,我得到:
iz1qFlQJfs6Ycp+gcc2z4w==
Run Code Online (Sandbox Code Playgroud)
这是你的PHP程序得到的.
更新(2016年6月12日):从Java 8开始,JavaSE最终附带了一个记录的base64编解码器.而不是
return new sun.misc.BASE64Encoder().encode(encrypted);
Run Code Online (Sandbox Code Playgroud)
你应该做点什么
return Base64.Encoder.encodeToString(encrypted);
Run Code Online (Sandbox Code Playgroud)
或者,使用第三方库(例如commons-codec)进行base64编码/解码,而不是使用未记录的内部方法.
| 归档时间: |
|
| 查看次数: |
4248 次 |
| 最近记录: |