Как отформатировать данные для правильного дешифрования шестнадцатеричных строк в CryptoJS

#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. Вы спасаете жизнь! Не могу отблагодарить вас!