javascript - 解密AES十六进制消息完成与服务器的相互认证

标签 javascript encryption cryptography cryptojs

我正在尝试遵循引用文档提供的这些说明:

变量 A 包含使用变量 B 加密的 16 字节随机数序列。

您应该使用变量 B 解密它并将其填充到变量 A 的末尾。

整个 32 字节变量将使用变量 B 进行解密并发送回服务器,以便成功进行身份验证。

您应该使用 AES128 CBC 密码模式进行解密。

变量A(16字节):e06e3e2ea024bba1185c33d64d2033b6
变量B(16字节):41435231323535552d4a312041757468

我在 CryptoJS 中的尝试

const message = 'e06e3e2ea024bba1185c33d64d2033b6';
const key = '41435231323535552d4a312041757468';

const decryptedMsg = CryptoJS.AES.decrypt(
  message,
  key,
  {
    mode: CryptoJS.mode.CBC,
  }
);

console.log(decryptedMsg.toString());

这一切产生的是一个空字符串。我在加密方面没有太多经验,如果能找到解决方案,我将不胜感激,以便我可以构建最终的 32 字节十六进制值并成功进行身份验证。

最佳答案

  • 以下内容适用于解密方法的参数,here :

    1. 参数:密文为CipherParams(如果在此处传递字符串,则默认情况下会进行 Base64 解码,但此处并非如此)
    2. 参数:key as WordArray(如果在此处传递字符串,则会将其解释为密码短语,从中派生出 key 和 IV,但此处无意)
    3. 参数:模式、初始化向量(IV)和填充

    然后您可以按如下方式解密:

    var CryptoJS = require("crypto-js"); 
    
    function decrypt(hexCiphertext, hexKey, hexIV){    
        var cipherParams = CryptoJS.lib.CipherParams.create(
            {ciphertext: CryptoJS.enc.Hex.parse(hexCiphertext)}
        );
        var key = CryptoJS.enc.Hex.parse(hexKey);
        var iv = CryptoJS.enc.Hex.parse(hexIV);
        var decrypted = CryptoJS.AES.decrypt(
            cipherParams,
            key,
            {iv: iv, padding: CryptoJS.pad.NoPadding, mode: CryptoJS.mode.CBC}
        );
        return decrypted;
    }
    
  • CBC 模式使用 IV,应取自规范。结果取决于这个 IV,即如果您使用了错误的 IV,解密将给出错误的结果。如果规范中没有 IV,您只能猜测并尝试,例如一个0-运气向量。填充也必须取自规范。由于根据解密第一部分的描述,加密后的消息和解密后的消息具有相同的长度(即16字节),显然没有使用填充(CryptoJS.pad.NoPadding)。

  • 以下内容适用于解密的第一部分(假设 IV 为 0 向量):

    var hexMessage = 'e06e3e2ea024bba1185c33d64d2033b6';
    var hexKey = '41435231323535552d4a312041757468';
    var hexIV = '00000000000000000000000000000000';
    var decryptedStep1 = decrypt(hexMessage, hexKey, hexIV);
    var hexDecryptedStep1 = CryptoJS.enc.Hex.stringify(decryptedStep1)
    console.log(hexDecryptedStep1);
    

    输出如下:

    93fd6fa1ee388d326535abf7bd66310a
    

    对于第二部分(假设 IV 为 0 向量):

    var hexMessageStep2 = hexMessage + hexDecryptedStep1;
    var decryptedStep2 = decrypt(hexMessageStep2, hexKey, hexIV);
    var hexDecryptedStep2 = CryptoJS.enc.Hex.stringify(decryptedStep2);
    console.log(hexDecryptedStep2);
    

    输出如下:

    93fd6fa1ee388d326535abf7bd66310ac57db5bd524becba57445a9dbc536d0d 
    

关于javascript - 解密AES十六进制消息完成与服务器的相互认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58775043/

相关文章:

c# - 一种使文件只能由特定程序解密的方法?

javascript - 具有 Rails Assets 管道的 JSHint 需要

javascript - 如何使用 vanilla javascript 确定 <div> 是否可滚动?

javascript - 将 if/else 语句转换为 switch 语句

java - 如何加密 BufferedImage 使其只能由程序读取?

c# - 读取/写入 Excel 2007 受密码保护的文档

javascript - Python - 用于已知解密函数的 Javascript 加密函数

javascript - 如何向数据表添加复选框

ruby-on-rails - has_secure_password 不加密 password_digest Ruby on Rails

java - 使用 AES/ECB/NoPadding 加密/解密