Я пытаюсь воспроизвести операцию шифрования с использованием AES-256-CCM, которая в настоящее время выполняется на Java с поставщиком Bouncy Castle. При попытке выполнить ту же операцию в PHP с использованием openssl я не могу найти набор параметров, который выдает тот же результат.
Поскольку режимы AEAD были недавно добавлены в PHP (7.1), документации о том, как это работает, недостаточно.
Минимальный пример «рабочего» шифрования в Java выглядит следующим образом:
public static void main(String args[]) {
try {
java.security.Security.addProvider(new BouncyCastleProvider());
byte[] key = Base64.decodeBase64("Z4lAXU62WxDi46zSV67FeLj3hSK/th1Z73VD4/y6Eq4=".getBytes());
byte[] iv = Base64.decodeBase64("rcFcdcgZ3Q/A+uHW".getBytes());
SecretKey aesKey = new SecretKeySpec(key, 0, key.length, "AES");
Cipher aesCipher = Cipher.getInstance("AES/CCM/NoPadding", "BC");
aesCipher.init(1, aesKey, new IvParameterSpec(iv));
byte[] encrypted = aesCipher.doFinal("test".getBytes());
System.out.println(Hex.encodeHex(encrypted));
// Output: 411d89ff74205c106d8d85a8
}
catch (Throwable e) {
e.printStackTrace();
}
}
Поскольку я пытаюсь воспроизвести это с использованием двух разных библиотек и языков, я установил ключ и iv на известные значения.
При попытке воспроизвести это с использованием PHP и openssl я пытаюсь с помощью следующего кода
$key = base64_decode("Z4lAXU62WxDi46zSV67FeLj3hSK/th1Z73VD4/y6Eq4=");
$iv = base64_decode('rcFcdcgZ3Q/A+uHW');
$data = 'test';
$tag = null;
$encrypted = openssl_encrypt($data,'aes-256-ccm', $key,OPENSSL_RAW_DATA, $iv, $tag,"",8);
echo(bin2hex($encrypted . $tag));
// d1a7403799b8c37240f36edb
Очевидно, что результаты не совпадают. В поисках ответа относительно того, что является неправильным, я создал ту же самую операцию, используя SJCL в javascript. Пример для этого:
var data = "test";
var key = sjcl.codec.base64.toBits("Z4lAXU62WxDi46zSV67FeLj3hSK/th1Z73VD4/y6Eq4=");
var iv = sjcl.codec.base64.toBits("rcFcdcgZ3Q/A+uHW");
var p = {
adata: "",
iter: 0,
mode: "ccm",
ts: 64,
ks: 256,
iv: iv,
salt: ""};
var encrypted = sjcl.encrypt(key, data, p, {});
console.log(encrypted);
// Output: {"iv":"rcFcdcgZ3Q/A+uHW","v":1,"iter":0,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"","ct":"QR2J/3QgXBBtjYWo"}
// QR2J/3QgXBBtjYWo === 411d89ff74205c106d8d85a8
Библиотеки Bouncy Castle и SJCL выдают один и тот же результат, но я не могу сказать, что отличается.
Я попытался предварительно обработать ключ с PBKDF2, как предложено в Шифрование в Javascript с помощью SJCL и дешифрование в PHP без успеха. Я попытался SHA256 ‘ключ без успеха.
Почему выходные данные в php / openssl отличаются от Bouncy Castle и SJCL?
Задача ещё не решена.
Других решений пока нет …