#javascript #node.js #encryption #cryptojs #node-crypto
#javascript #node.js #шифрование #cryptojs #узел-криптография
Вопрос:
У меня есть TCP-сервер, который получает информацию через прямой IP. Я получаю эту информацию, зашифрованную в AES-128-CBC. (шестнадцатеричный байтовый буфер) Затем я превращаю буфер в строку шестнадцатеричных байтов без пробелов. «originalMsg»
Мне передается IV, зашифрованное сообщение, и у меня есть жестко заданный ключ. Я все еще не могу получить сообщение для правильного дешифрования. Обычно я получаю совершенно другую расшифровку или пустую строку. Я предполагаю, что одна или несколько моих переменных имеют неправильный формат?
До этой недели у меня не было опыта работы с криптологией, но это моя задача. Итак, я прошу прощения, если проблема в чем-то незначительном.
Я получаю данные от моего коллеги с языка C. Я боюсь, что CryptoJS несовместим с передаваемыми мне данными? Любая помощь приветствуется.
code.js
const CryptoJS = require("crypto-js");
var originalMsg = "5303F15FB8317A010300000000000001F3E0C003E24340E4E4"
var encrypted = "00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC"
var key = "242E389B1672B4ECEA92FE7466DF3A52"
var iv = "0000E34500FF0000000000FF00000000"
var decryptData2 = function(encryptedData) {
var C = CryptoJS;
var Key = CryptoJS.enc.Hex.parse("242E389B1672B4ECEA92FE7466DF3A52")
var IV = CryptoJS.enc.Hex.parse("0000E34500FF0000000000FF00000000")
// I have tried
var decryptedText = C.AES.decrypt(encryptedData, Key, {
iv: IV,
mode: C.mode.CBC,
padding: C.pad.Pkcs7
});
return decryptedText.toString(CryptoJS.enc.Utf8);
}
var result = decryptData2(CryptoJS.enc.Hex.parse("00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC"))
console.log(result);
Редактировать:
Обновлены переменные iv и encrypted
//old vars
encrypted ="00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC"
iv = "02C4100000E34500FF0000000000FF00"
Комментарии:
1. Извините, но ваш образец набора данных не работает независимо от вашего языка программирования. Я предполагаю, что «зашифрованное» значение представляет собой зашифрованный текст в шестнадцатеричной строке (после завершения шифрования) и имеет длину 38 байт, но при использовании AES в режиме CBC вывод должен быть кратен 16 (поэтому он должен быть длиной 48 байт). С другой стороны — при шифровании исходного сообщения (это строка длиной 50 символов или значение длиной 25 байт [в шестнадцатеричном кодировании]?) Я не могу получить зашифрованное значение. Итак, вкратце: пожалуйста, проверьте значения и, возможно, отредактируйте свой пост, спасибо.
2. Большое вам спасибо за попытку, я подумал, что, возможно, они тоже дали мне неправильные данные, поэтому я попрошу их проверить и отредактирую сообщение. Спасибо.
3. Это 25 байт, которые я превращаю в строку.
4. @MichaelFehr Я обновил переменные до того, что считаю правильным, но он все еще не работает.
Ответ №1:
Всегда полезно полагаться на образцы данных, потому что это очень помогает в поиске рабочего решения. Ниже вы найдете пример программы, которая смогла расшифровать сообщение.
Некоторые замечания о том, как это работает:
а) Я конвертирую все предоставленные данные в массивы слов Crypto-JS, чтобы они были совместимы с методами криптографии:
var key = CryptoJS.enc.Hex.parse("242E389B1672B4ECEA92FE7466DF3A52");
б) чтобы увидеть, какие зашифрованные данные я должен использовать для дешифрования, я сначала шифрую originalMsg и получаю этот вывод:
ciphertext: 2b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
c.txt exp: 00000003c4302b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
Первая строка — это зашифрованный «originalMsg», вторая строка — данные, которые вы определили как «зашифрованные» — видите разницу? Как я уже отмечал ранее, зашифрованное значение слишком длинно на 6 байт (оно должно быть кратно 16, ваше «зашифрованное» имеет длину 38 байт).
c) для попытки дешифрования требуется ввод в кодировке base64 (есть и другие способы, этот способ является наиболее удобным для меня, чтобы использовать его здесь), поэтому сначала я кодирую массив слов «encrypted» в (в кодировке Base64) «encryptedBase64» и представляю строку функции aesCbcDecrypt. Поскольку данные слишком длинные, вывод отсутствует.
var encryptedBase64 = CryptoJS.enc.Base64.stringify(encrypted);
var decrypted = aesCbcDecrypt(key, iv, encryptedBase64);
console.log("decrypted: " decrypted);
result:
decrypted:
d) теперь я отсекаю первые 6 байтов (12 шестнадцатеричных «символов») от зашифрованных и использую оставшиеся данные для той же функции дешифрования:
var encrypted2 = CryptoJS.enc.Hex.parse("2B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC");
console.log("encrypted2 length: " encrypted2.sigBytes);
var encrypted2Base64 = CryptoJS.enc.Base64.stringify(encrypted2);
var decrypted2 = aesCbcDecrypt(key, iv, encrypted2Base64);
console.log("decrypted2: " decrypted2);
console.log("orig.Msg : " originalMsgHex);
result:
decrypted2: 5303f15fb8317a010300000000000001f3e0c003e24340e4e4
orig.Msg : 5303F15FB8317A010300000000000001F3E0C003E24340E4E4
Значение decrypted2 теперь равно originalMsg.
Если вы хотите увидеть, как код выполняется в онлайн-компиляторе — вот ссылка: https://repl.it/@javacrypto/SoCryptoJsDecrypt#index.js
Я оставляю на ваше усмотрение объединить эту информацию, чтобы получить программное решение, поскольку это должно только объяснить, как получить зашифрованные данные.
полный вывод:
key length: 16
iv length: 16
ciphertext: 2b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
c.txt exp: 00000003c4302b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
encrypted length: 38
decrypted:
encrypted2 length: 32
decrypted2: 5303f15fb8317a010300000000000001f3e0c003e24340e4e4
orig.Msg : 5303F15FB8317A010300000000000001F3E0C003E24340E4E4
Предупреждение безопасности: код не имеет обработки исключений и предназначен только для образовательных целей.
полный код:
const CryptoJS = require("crypto-js");
var originalMsgHex = "5303F15FB8317A010300000000000001F3E0C003E24340E4E4";
var originalMsg = CryptoJS.enc.Hex.parse(originalMsgHex);//("5303F15FB8317A010300000000000001F3E0C003E24340E4E4");
var encrypted = CryptoJS.enc.Hex.parse("00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC");
var key = CryptoJS.enc.Hex.parse("242E389B1672B4ECEA92FE7466DF3A52");
var iv = CryptoJS.enc.Hex.parse("0000E34500FF0000000000FF00000000");
console.log("key length: " key.sigBytes);
console.log("iv length: " iv.sigBytes);
// encryption of originalMsg
var ciphertext = aesCbcEncrypt(key, iv, originalMsg);
console.log("ciphertext: " ciphertext);
console.log("c.txt exp: " encrypted);
// decryption of encryption fails due to wrong length (not multiple of 16)
console.log("encrypted length: " encrypted.sigBytes); // result: 38
// prepare encrypted for decryption by base64encoding
var encryptedBase64 = CryptoJS.enc.Base64.stringify(encrypted);
var decrypted = aesCbcDecrypt(key, iv, encryptedBase64);
console.log("decrypted: " decrypted);
// cutting off the first 6 bytes from encrypted
var encrypted2 = CryptoJS.enc.Hex.parse("2B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC");
console.log("encrypted2 length: " encrypted2.sigBytes);
var encrypted2Base64 = CryptoJS.enc.Base64.stringify(encrypted2);
var decrypted2 = aesCbcDecrypt(key, iv, encrypted2Base64);
console.log("decrypted2: " decrypted2);
console.log("orig.Msg : " originalMsgHex);
function aesCbcEncrypt(keyF, ivF, data) {
const cipher = CryptoJS.AES.encrypt(data, keyF,
{
iv: ivF,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
return cipher.ciphertext;
}
function aesCbcDecrypt(keyF, ivF, ciphertext) {
const cipher = CryptoJS.AES.decrypt(ciphertext, keyF,
{
iv: ivF,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
return cipher;
}
Комментарии:
1. Вы спасаете жизнь! Не могу отблагодарить вас!