node.js - 使用 vb.net AES/CBC 加密字符串并需要使用 JavaScript CryptoJS 解密

标签 node.js vb.net encryption aes cryptojs

我有一个 vb.net Windows 窗体应用程序,可将字符串加密到文件中。我现在需要 JavaScript 来解密该值。我尝试过使用 CryptoJS,但我在语法以及如何以正确的格式获取密码、盐和初始化向量以在 CryptoJS.PBKDF2 中使用方面遇到困难(假设这是正确的使用方式)。

调用方式

Dim encryptedComplianceValue = encrypt2(complianceValue, "Password", "Salt Value", "SHA1", 2, "@1B2c3D4e5F6g7H8", 256)

加密方式

Public Function encrypt2(ByVal plainText As String, ByVal passPhrase As String, ByVal saltValue As String, ByVal hashAlgorithm As String, ByVal passwordIterations As Integer, ByVal initVector As String, ByVal keySize As Integer) As String

    Dim initVectorBytes As Byte()
    initVectorBytes = Encoding.ASCII.GetBytes(initVector)

    Dim saltValueBytes As Byte()
    saltValueBytes = Encoding.ASCII.GetBytes(saltValue)

    Dim plainTextBytes As Byte()
    plainTextBytes = Encoding.UTF8.GetBytes(plainText)

    Dim password As Rfc2898DeriveBytes
    password = New Rfc2898DeriveBytes(passPhrase, saltValueBytes, passwordIterations)

    Dim keyBytes As Byte()
    keyBytes = password.GetBytes(keySize / 8)

    Dim symmetricKey As RijndaelManaged
    symmetricKey = New RijndaelManaged()

    symmetricKey.Mode = CipherMode.CBC

    Dim encryptor As ICryptoTransform
    encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)

    Dim memoryStream As MemoryStream
    memoryStream = New MemoryStream()

    Dim cryptoStream As CryptoStream
    cryptoStream = New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
    cryptoStream.FlushFinalBlock()

    Dim cipherTextBytes As Byte()
    cipherTextBytes = memoryStream.ToArray()

    memoryStream.Close()
    cryptoStream.Close()

    Dim cipherText As String
    cipherText = Convert.ToBase64String(cipherTextBytes)

    Return cipherText
End Function

JavaScript

function decryptMsg256() 
{
    var keySize = 256;
    var iterations = 2;
    var algorithm = 'AES-256-CBC';

    // the password that user provides
    var userPass = "Password"; 
    console.log("user pass : " + userPass);

    // get the encrypted msg 
    var encMsg64 = "v6shkblimfQMOoa8VxICjQ==";
    var encMsg = CryptoJS.enc.Base64.parse(encMsg64);



    //var salt =CryptoJS.enc.Utf8.parse("Mon,07-Mar-2016 18:50:46 GMT");
    var salt = "Salt Value";
    console.log('salt:  '+ salt);
    var saltbytes = [];

    for (var i = 0; i <salt.length; ++i) {
        saltbytes .push(salt.charCodeAt(i));
    }
    console.log('saltbytes:  '+ saltbytes );

    //var iv =CryptoJS.enc.Utf8.parse("@1B2c3D4e5F6g7H8");
    var iv = "@1B2c3D4e5F6g7H8";
    console.log('IV:  '+ iv);
    var ivbytes = [];

    for (var i = 0; i <iv.length; ++i) {
        ivbytes.push(iv.charCodeAt(i));
    }
    console.log('ivbytes:  '+ ivbytes );

    //var saltBuffer = new Buffer(salt);
    //var passwordBuffer = new Buffer(userPass);

    var key = CryptoJS.PBKDF2(userPass, saltbytes,{keyBytes: 32,      iterations: 2 });
    //var key = CryptoJS.PBKDF2(userPass, salt, iterations, keySize/8);
    //var decipher = CryptoJS.createDecipheriv(algorithm, key, iv);

    console.log( 'key: '+ key);
    var keybytes = [];

    for (var i = 0; i <key.length; ++i) {
        keybytes.push(key.charCodeAt(i));
    }
    console.log('keybytes:  '+ keybytes);


    //var plainText="Hello, World!";

    //console.log('Plain Text  '+ plainText );

    //var encMsg = CryptoJS.AES.encrypt(plainText, key,  {
         //               iv:iv,
          //            mode: CryptoJS.mode.CBC,
           //             padding: CryptoJS.pad.Pkcs7
    //      });


    //console.log('Encrypted Message  '+ encMsg );




    var decText = '';

    var decMsg = CryptoJS.AES.decrypt( encMsg, key, {
                    iv:iv,
                    mode: CryptoJS.mode.CBC,
                    //padding: CryptoJS.pad.Pkcs7
                    } );
    //console.log( "decryptedData = " + decMsg );

    // convert to UTF8 string
    decText = decMsg.toString( CryptoJS.enc.Utf8);
    console.log( "decryptedText = " + decText );

}

最佳答案

您有多个问题:

  • 您的 IV 是一个简单的 ASCII 字符串,因此您可以使用

    轻松将其解析为二进制格式
    var iv = CryptoJS.enc.Utf8.parse("@1B2c3D4e5F6g7H8");
    
  • 请勿将自定义“二进制”格式与 saltbytes.push(salt.charCodeAt(i)); 或类似格式一起使用。您需要使用 CryptoJS 的 native 格式,可通过

    CryptoJS.enc.<Encoder>.parse(string)
    
  • PBKDF2 的输出大小由 keySize 指定,而不是 keyBytes:

    var key = CryptoJS.PBKDF2(userPass, salt, {keySize: 256/32,      iterations: 2 });
    
  • 解密函数期望密文是 CipherParams 对象。好东西,鸭子打字有效:

    var decMsg = CryptoJS.AES.decrypt({
        ciphertext: encMsg
    }, key, {
        iv: iv
    });
    

关于node.js - 使用 vb.net AES/CBC 加密字符串并需要使用 JavaScript CryptoJS 解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35853392/

相关文章:

javascript - nodejs - 将客户端时间戳存储在数据库中

ruby-on-rails - Rails 3/设计 : Password salt no longer being created?

node.js - Hubot Windows 服务

javascript - JavaScript 和 Mocha 的单元测试

c# - 将 ProcessStartInfo.WorkingDirectory 设置为 UNC 路径

.net - 从字典生成数据表

javascript - 获取加密的缓冲区数据以用作客户端解密的 ArrayBuffer

c# - 'CryptoStream' 的最佳重载没有名为 'leaveOpen' 的参数

javascript - 如何同时保存两个相互关联的模型?

asp.net - 如何改进具有多个 case 语句的页面设计