У меня есть кусок кода на PHP
function encrypt($data){
$data = "{\"userId\":11,\"email\":\"[email protected]\",\"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\":\"[email protected]\",\"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-код отличаются:
mcrypt
(см. здесь). Напротив, в Java-коде используется PKCS7-Padding (в Java также называемый PKCS5). Чтобы использовать Zero-Byte-Padding в Java-коде, сначала отключите заполнение PKCS7, заменив AES/CBC/PKCS5PADDING
на AES/CBC/NoPadding
. Во-вторых, реализовать вручную Zero-Byte-Padding, то есть добавить n
0-значений (с 0 <= n < 16
) к последовательности байтов сообщения, пока длина не будет соответствовать целому числу, кратному размеру блока (16 байт).С этими изменениями Java- и PHP-код будут давать одинаковый результат, если используется один и тот же ключ и один и тот же IV (кстати, ключ в Java-коде имеет длину 15 байт, что приводит к InvalidKeyException (Invalid AES key length: 15 bytes)
).
Обратите внимание на mcrypt
устарела и Zero-Byte-Padding ненадежен. Если у вас есть возможность изменить заполнение, PKCS7 предпочтительнее.
Спасибо. Это правильный ответ. Уже исправил, добавив pkcs5 в php-код.
Является ли то же значение вектора инициализации IV, которое вы используете в java?