Как сделать криптографическую функцию в javascript, например Rfc2898DeriveBytes

У меня есть проект в vb.net/Jquery. Где я использую функцию шифрования для проверки подключения к моей внутренней сети.

 Public Shared Function ValidatePassword(passwordToTest As String, passwordParam As paramPassword) As Boolean
        Dim hash() As Byte = passwordParam.hashByteArray
        Dim testHash() As Byte = PBKDF2(passwordToTest, passwordParam.saltByteArray, passwordParam.iteration, passwordParam.hashByteArraySize)
        Return SlowEquals(hash, testHash)
    End Function

    Private Shared Function SlowEquals(a() As Byte, b() As Byte) As Boolean
        Dim diff As UInteger = CUInt(a.Length) Xor CUInt(b.Length)
        For i As Integer = 0 To Math.Min(a.Length, b.Length) - 1
            diff = CUInt(a(i) Xor b(i)) Or diff
        Next
        Return diff = 0
    End Function

    Private Shared Function PBKDF2(password As String, salt() As Byte, iterations As Integer, outputBytes As Integer) As Byte()
        Dim PBKDF2_hasher As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(password, salt)
        PBKDF2_hasher.IterationCount = iterations
        Return PBKDF2_hasher.GetBytes(outputBytes)
    End Function

Теперь, если я не в сети, я хочу проверить соединение с indexdb. Затем я снова и снова пытаюсь смоделировать бит этой функции. Я вижу это, но нужен node.js. Мне не удалось адаптироваться, и я предпочитаю не ставить node.js только для этого. Я вижу это другое здесь, но оно очень длинное, и я не смог поместить результат в переменную, и в худшем случае результат отличается от моего хэша... Я вижу cryptojs из Google, но не понимаю, как его использовать. Когда я загружаю его, у меня есть 2 папки: компоненты / роллапы ??

Кто-нибудь может помочь мне найти простой способ использования криптобиблиотеки и как ее использовать?

Rfc2898DeriveBytes реализует PBKDF2, который поддерживается CryptoJS и криптомодулем NodeJS. Вы можете найти примеры в соответствующей документации, например. здесь и здесь. Попробуйте реализацию и, если вы застряли, опубликуйте свой самый последний код вместе с описанием проблемы.
Topaco 23.12.2020 17:23

Я уже нашел эту страницу, но не смог их реализовать. Как я могу вставить в Visual Studio, как вы можете видеть в моем первом посте. И я никогда не использую node.js. Вот почему криптографы привлекают мое внимание, но как их использовать

YannickIngenierie 23.12.2020 18:27

Или простой пример кода будет очень хорош, просто чтобы понять, включает и другие вещи, связанные с этим.

YannickIngenierie 23.12.2020 18:48

Для интеграции NodeJS в Visual Studio вы можете найти достаточно информации в Интернете, например. здесь . Как использовать CryptoJS в среде NodeJS, также можно найти, например. здесь.

Topaco 23.12.2020 18:58
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
354
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я создаю новый пост, чтобы четко опубликовать тестовый код с использованием cryptojs. В aspx

  <script src = "/Scripts/Crypto/core.js"></script>
<script src = "/Scripts/Crypto/hmac.js"></script>
<script src = "/Scripts/Crypto/sha1.js"></script>
<script src = "/Scripts/Crypto/pbkdf2.js"></script>
<script src = "/Scripts/Pages/test.js"></script>

В aspx.vb

Public Class NewPwD
    Property hash As String
    Property salt As String
End Class
<Services.WebMethod()>
Public Shared Function SetPassWord() As NewPwD
    Dim ret As New NewPwD
    Dim csprng As RNGCryptoServiceProvider = New RNGCryptoServiceProvider()
    Dim salt(63) As Byte
    csprng.GetBytes(salt)
    Dim hash() As Byte = PBKDF2("Toto", salt, 10, 64)
    ret.hash = Convert.ToBase64String(hash)
    ret.salt = Convert.ToBase64String(salt)
    Return ret
End Function
Private Shared Function PBKDF2(password As String, salt() As Byte, iterations As Integer, outputBytes As Integer) As Byte()
    Dim PBKDF2_hasher As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(password, salt)
    PBKDF2_hasher.IterationCount = iterations
    Return PBKDF2_hasher.GetBytes(outputBytes)
End Function

В тесте.JS

$(function () {
$.ajax({
    type: "POST", url: '/test.aspx/SetPassWord',  contentType: 'application/json; charset=utf-8', dataType: "json",
    success: function (msg) {   
        AfficheMsgRetour(ValidatePassWord("Toto", msg.d.hash,msg.d.salt, 64, 10));
    }
});
});

function ValidatePassWord(password, hashedPwd, saltString, saltlen, iterations) {
var key = CryptoJS.PBKDF2(password, saltString, { keySize: saltlen, iterations: iterations });
var str = _arrayBufferToBase64(key.words);
return (hashedPwd === str);
}  

function _arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
function _base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
    bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}

И, как вы можете себе представить... результаты различаются между vb.net и javacript В ValidatePassWord я в последней строке:

6lHrQquUwxciBYFdokTmPn0ub+eeZrN0rwgRp2WQqxDplCq9O3Z6WxlR/KjDl24Ziv3GY9q5F9PV6CXprw3M2Q== nUeo17n1s3eJ5wJrFp4PBXFwks8lfS9lCMu8gRLR/fdWIkzRCxQIQ7OVZK0RmzcDsTcQtU2WiLh5OqXtAFyYa4k=

У меня большие сомнения в параметре соли между base64string и буфером... но я пробую эти 3 решения... всегда неправильный результат в конце

        ret.salt = System.Text.Encoding.UTF8.GetString(hash, 0, hash.Length) 'System.Text.Encoding.Default.GetString(salt) 'Convert.ToBase64String(salt)

Затем я пытаюсь заставить соль

Public Shared Function SetPassWord() As NewPwD
    Dim ret As New NewPwD
    Dim csprng As RNGCryptoServiceProvider = New RNGCryptoServiceProvider()
    Dim originalsalt As String = "azertyuiop"
    Dim salt As Byte() = System.Text.Encoding.Default.GetBytes(originalsalt)
    
    Dim hash() As Byte = PBKDF2("Toto", salt, 10, 64)
    ret.hash = Convert.ToBase64String(hash)
    ret.salt = originalsalt 
    Return ret
End Function

Но всегда одна и та же проблема не соответствует

Я бы порекомендовал опубликовать полный набор образцов данных. т.е. для кода VB приведите пример для ret.salt (в настоящее время отсутствует) и ret.hash (с сохранением остальных параметров PBKDF2: пароль (Toto), итерации (10), размер ключа (64 байта)). Я предполагаю, что оба данных соответствуют msg.d.salt и msg.d.hash в JavaScript, верно? С такими выборочными данными было бы намного проще проверить ValidatePassword или CryptoJS.PBKDF2 и при необходимости скорректировать. Без обид, но было бы лучше, если бы вы отредактировали свой вопрос и прикрепили эту информацию, а не публиковали ответ.

Topaco 24.12.2020 18:11

Я использовал ваш код VB для создания необходимых образцов данных. Вы можете найти возможную реализацию JavaScript для проверки с использованием CryptoJS в моем ответе.

Topaco 24.12.2020 19:18
Ответ принят как подходящий

Я использовал ваш код VB, чтобы получить следующие (в кодировке Base64) образцы данных для хэша и соли:

Hash:       bAZiQwC3BDvAzUEp/9MJ2HqNPvsB24V5HUnz8YZA1sGP8BOK0H1UhiUSMV4jipPiZiiKXQE8g0jKJt+bzcwj1Q==
Salt:       ByMK17y9LCHLtX9+N6c9UlXKwv9r5Q9YPZVwQ1s1a4z9R4vufoFD4ezqfN3iE+mt7cOl9CxGVxYMLXVbdOR83w==

Так как код VB я взял без изменений, остальные параметры PBKDF2 такие:

Password:   Toto
Iterations: 10
Key size:   64 bytes

Одна из возможных реализаций проверки пароля в JavaScript с использованием CryptoJS:

function ValidatePassWord(password, hashedPwd, saltString, keylen, iterations) {
    var saltWA = CryptoJS.enc.Base64.parse(saltString);
    var hashedPwdToCompareWA = CryptoJS.PBKDF2(password, saltWA, { keySize: keylen / 4, iterations: iterations });
    var hashedPwdToCompare = CryptoJS.enc.Base64.stringify(hashedPwdToCompareWA);
    //console.info(hashedPwdToCompare);
    return (hashedPwd === hashedPwdToCompare);
} 

// Data from VB Code
var password = 'Toto';
var keylen = 64;
var iterations = 10;
var hashedPwd = 'bAZiQwC3BDvAzUEp/9MJ2HqNPvsB24V5HUnz8YZA1sGP8BOK0H1UhiUSMV4jipPiZiiKXQE8g0jKJt+bzcwj1Q==';
var saltString = 'ByMK17y9LCHLtX9+N6c9UlXKwv9r5Q9YPZVwQ1s1a4z9R4vufoFD4ezqfN3iE+mt7cOl9CxGVxYMLXVbdOR83w==';

// Successful verification
var verified = ValidatePassWord(password, hashedPwd, saltString, keylen, iterations);
console.info('Test - successful verification:', verified);

// Failed verification
var otherHashedPwd = 'xAZiQwC3BDvAzUEp/9MJ2HqNPvsB24V5HUnz8YZA1sGP8BOK0H1UhiUSMV4jipPiZiiKXQE8g0jKJt+bzcwj1Q==';
var verified = ValidatePassWord(password, otherHashedPwd, saltString, keylen, iterations);
console.info('Test - failed verification:    ', verified);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

CryptoJS использует тип данных WordArray (отмеченный WA во фрагменте) и предлагает различные кодировщики для преобразования, например. CryptoJS.enc.Base64 для конвертации из/в Base64, с. здесь. Это делает методы _arrayBufferToBase64 и _base64ToArrayBuffer устаревшими.

Обратите внимание, что количество итераций, равное 10, обычно слишком мало. Счетчик итераций предназначен для замедления злоумышленника и должен быть установлен как можно большим (например, 10 000), сохраняя при этом приемлемую производительность приложения.

Другие вопросы по теме