У меня есть java-код, который создает для меня код шифрования aes. Я пытаюсь использовать его в javascript, используя crypto-js, но оба кода предоставляют разные ключи. Я не знаю, почему и как получить тот же ключ здесь - это мой код
public static String encrypt(String text, byte[] iv, byte[] key)throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
System.out.println("KEY SPECCCC: "+keySpec);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivSpec);
byte [] results = cipher.doFinal(text.getBytes("UTF-8"));
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(results);
}
Код JavaScript
require(["crypto-js/core", "crypto-js/aes"], function (CryptoJS, AES) {
ciphertext = CryptoJS.AES.encrypt(JSON.stringify(jsondata),
arr.toString(),arr.toString());
});
строка в utf-8
var utf8 = unescape(encodeURIComponent(key));
var arr = [];
for (var i = 0; i < utf8.length; i++) {
arr.push(utf8.charCodeAt(i));
}
Прежде всего, даже жесткий код работает отлично, вы не сможете его правильно расшифровать, потому что, когда вы создаете свой AES-шифр в Java, вы используете CBC Cipher, и вы реализуете алгоритм Padding, который является PKCS5Padding. Таким образом, ваш код Java выполняет следующие действия; Когда он получает вход, он сначала делит его на 16 бит блоков, а если ваш вход не делится на 16 в целом, тогда напоминания будут заполнены для заполнения блока с таким же количеством напоминаний. Вы можете видеть, что я имею в виду под следующим картина.
Таким образом, он будет делать шифрование с заполненными шифрами в java-стороне, но в Javascript Part. Вы не объявляете, какой тип режима Aes будет использовать, и не объявляйте, какой тип Padding он должен делать. Поэтому вы должны добавить эти значения в свой код. Вы можете выполнить поиск следующих частей кода.
mode:CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
О разных ключах, связанных с тем, что вы отправляете Byte [] в свой метод Encrypt, используйте этот неизвестный байт [], когда вы создаете свой ключ. Вы не упомянули, почему ваш метод шифрования будет использоваться в вашей программе, но вы должен создать этот "Byte [] ключ" одинаковым образом в обоих методах. Например, вы можете ссылаться на следующий код в качестве примера создания этого, но это не безопасный способ генерации ключей, который я только что добавил, чтобы показать вам, что я имею в виду под вами должен генерировать обе клавиши одинаковым образом.
//DONT USE THIS IMPLEMENTATION SINCE IT IS NOT SAFE!
byte[] key = (username + password).getBytes("UTF-8");
Java-код генерирует зашифрованную строку и для JavaScript также генерировать ту же зашифрованную строку, следующий код работает!
(function (CryptoJS) {
var C_lib = CryptoJS.lib;
// Converts ByteArray to stadnard WordArray.
// Example: CryptoJS.MD5(CryptoJS.lib.ByteArray ([ Bytes ])).toString(CryptoJS.enc.Base64);
C_lib.ByteArray = function (arr) {
var word = [];
for (var i = 0; i < arr.length; i += 4) {
word.push (arr[i + 0] << 24 | arr[i + 1] << 16 | arr[i + 2] << 8 | arr[i + 3] << 0);
}
return C_lib.WordArray.create (word, arr.length);
};
})(CryptoJS);
var IVstring = CryptoJS.lib.ByteArray(your IV bytearray).toString(CryptoJS.enc.Base64);
var keystring = CryptoJS.lib.ByteArray(your KEY bytearray).toString(CryptoJS.enc.Base64);
var text = 'texttobeencrypted';
var key = CryptoJS.enc.Base64.parse(keystring);
var iv = CryptoJS.enc.Base64.parse(IVstring);
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv});
console.log(encrypted.toString());
Отредактировано: удалена ссылка на опасный сторонний ресурс.