【问题标题】:How to format data to correctly decrypt hex strings in CryptoJS如何格式化数据以正确解密 CryptoJS 中的十六进制字符串
【发布时间】:2021-03-07 14:37:51
【问题描述】:

我有一个通过直接 IP 接收信息的 TCP 服务器。我正在接收以 AES-128-CBC 加密的信息。(十六进制字节缓冲区)然后我将缓冲区转换为一串没有空格的十六进制字节。 “原味”

我通过了 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 和加密变量

//old vars
encrypted ="00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC"

iv = "02C4100000E34500FF0000000000FF00"


【问题讨论】:

  • 很抱歉,无论您的编程语言如何,您的示例数据集都无法正常工作。我假设“加密”值是十六进制字符串编码的密文(加密完成后),长度为 38 字节,但在 CBC 模式下使用 AES 时,输出必须是 16 的倍数(所以应该是 48字节长)。另一方面 - 在加密原始消息时(是 50 个字符长的字符串还是 25 个字节长的 [十六进制编码] 值?)我无法获得加密值。简而言之:请检查值并编辑您的帖子,谢谢。
  • 非常感谢您的尝试,我想也许他们也给了我错误的数据,所以我会请他们检查并编辑帖子。谢谢。
  • 我转成字符串的长度是25字节。
  • @MichaelFehr 我已将变量更新为我认为正确的值,但仍然无法正常工作。

标签: javascript node.js encryption cryptojs node-crypto


【解决方案1】:

依靠样本数据总是好的,因为这有助于找到可行的解决方案。您可以在下面找到能够解密消息的示例程序。

一些说明它是如何工作的:

a) 我正在将所有给定数据转换为 Crypto-JS 字数组以与加密方法兼容:

var key = CryptoJS.enc.Hex.parse("242E389B1672B4ECEA92FE7466DF3A52");

b) 查看我应该使用哪些加密数据进行解密,我首先加密 originalMsg 并获得以下输出:

ciphertext:             2b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
c.txt exp:  00000003c4302b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc

第一行是加密的“originalMsg”,第二行是您标识为“加密”的数据 - 看到区别了吗?正如我之前评论的那样,加密值太长了 6 个字节(它必须是 16 的倍数,您的“加密”长度为 38 个字节)。

c) 尝试解密需要 base64 编码的输入(还有其他方式,这种方式是我在这里使用它最方便的方式)所以首先我将单词数组“加密”编码为(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;
}

【讨论】:

  • 你是救生员!感激不尽!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 2020-11-11
  • 2019-01-30
  • 2017-12-17
  • 2022-07-08
  • 1970-01-01
相关资源
最近更新 更多