Зашифровать строку с помощью vb.net AES / CBC и расшифровать с помощью JavaScript 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 );

}

person bz23    schedule 07.03.2016    source источник
comment
FWIW, если вы делаете это только в узле, узел может выполнять PBKDF2 изначально в модуле crypto.   -  person mscdex    schedule 08.03.2016


Ответы (1)


У вас несколько проблем:

  • Ваш IV представляет собой простую строку ASCII, поэтому вы можете легко преобразовать ее в двоичный формат с помощью

    var iv = CryptoJS.enc.Utf8.parse("@1B2c3D4e5F6g7H8");
    
  • Не используйте свой собственный «двоичный» формат с saltbytes.push(salt.charCodeAt(i)); или подобным. Вам необходимо использовать собственный формат CryptoJS, который доступен через

    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
    });
    
person Artjom B.    schedule 07.03.2016
comment
Кстати, RijndaelManaged поддерживает несколько размеров блоков, но AES CryptoJS поддерживает только один размер блока (128 бит). Вы не должны слишком сильно зависеть от значений по умолчанию, которые могут быть неправильно установлены на 128. - person Artjom B.; 08.03.2016