Необходимо ли использовать получение ключа при использовании крипто-модуля Node? - PullRequest
0 голосов
/ 05 марта 2019

Мне нужно реализовать симметричное шифрование с использованием ключевой фразы пользователя в приложении NodeJS.При использовании crypto.createCipheriv() нужно ли выполнять какой-либо вывод ключа для ключевой фразы, чтобы получить значение для параметра key, или достаточно просто передать пользовательскую фразу как есть иоб этом позаботится реализация?

Ответы [ 2 ]

0 голосов
/ 10 марта 2019

Пароли не следует использовать в качестве ключей напрямую, но их можно использовать для создания ключа с KDF.Это потому, что ключ должен иметь определенный размер, а пароли слабые - они используют только ограниченный набор байтов и обычно содержат слова.Это делает их уязвимыми как для атак методом перебора, так и для атак по словарю.KDF не только создают длинные и однородные ключи, но и вводят рабочий фактор, который делает нецелесообразными атаки методом перебора.

createCipheriv() не изменяет содержимое или размер ключа.Это не упоминается в документации, но следует за исходным кодом (от createCipheriv: source , до Cipheriv: source , до createCipherWithIV: source , prepareSecretKey: source ) мы видим, что ключ используется как есть.Таким образом, ключ должен иметь правильный размер и достаточно сложный.

Crypto предоставляет два KDF на основе пароля, scrypt и PBKDF2.Лучше всего использовать scrypt, потому что он очень дорогой с точки зрения ресурсов процессора и памяти, и его можно настроить для параллельной обработки, тогда как PBKDF2 стоит только ресурсы процессора.Оба KDF требуют соли, которая должна быть длинной и случайной.

Создание ключа с помощью scrypt:

const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);

Создание ключа с помощью pbkdf2:

const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');

Где sha256 - базовый хэш, а 10000 - рекомендуемое минимальное количество итераций, определяющее коэффициент работы.В сценарии общий коэффициент работы является необязательным параметром со значением по умолчанию 16384 (2 ^ 14) и может быть установлен в options['cost'], где мы также можем установить размер блока и распараллеливание.Эти значения могут быть значительно увеличены в зависимости от ОС;Каждая операция должна занять около 100 мс.

Наконец, Argon2 считается очень хорошим KDF и, как и scrypt, он может быть скорректирован для использования процессора и памяти и параллельной обработки.Хотя Argon2 недоступен в crypto, он предоставляется другими пакетами Node.js.

0 голосов
/ 08 марта 2019

Сложность взлома шифра больше зависит от используемого алгоритма, чем от длины пароля.(опуская атаки брут-форс)

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

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


Более ранний ответ, немного не по теме.

TL; DR: лучший способ - обработать пароль в двоичном буфере (строке).

Симметричное шифрование точно основано на фактечто, имея секрет, вы можете выполнить обратную операцию. Симметричный означает, что операции обратимы.

Ваш язык программирования, инфраструктура или библиотека не имеют значения.

Некоторые различия находятся на этапе упаковки зашифрованного сообщения.Вы можете получить необработанное сообщение или красиво отформатированное сообщение, в котором вы добавили IV и содержимое в base64.

Вам также необходимо обработать ключ таким же образом.Но речь идет о кодировании big endian и little endian и кодировке символов, например: utf-8, latin2

IV - это дополнительная защита, направленная на создание разных зашифрованных сообщений для одного и того же входящего сообщения и секрета.,Но, как написано в последнем абзаце раздела, на который вы нацелены:

Они не должны быть секретными: IV обычно просто добавляются в незашифрованные сообщения зашифрованного текста.

В итоге: вам не нужно влиять на сам процесс шифрования, и вам нужно проверить, какие данные нужны Electron.

Например, моя процедура дешифрования (в узле, данные из PHP):

let crypto = {
  key: Buffer.from('secret in hex', 'hex'),
  cipher: 'aes-128-cbc',
  iv_size: 16
}
    let bData = Buffer.from(data.replace(/ /g,'+'), 'base64');
    let iv = bData.slice(0, crypto.iv_size);
    let text = bData.slice(crypto.iv_size);
    var decipher = crypt.createDecipheriv(crypto.cipher, crypto.key, iv);
    decipher.setAutoPadding(false);
    var decrypted = decipher.update(text,'hex','hex');
    decrypted += decipher.final('hex');

Для шифрования PHP:


    $data = mcrypt_encrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv);

    // Use base64 encoding to convert to a string
    return base64_encode($iv.$data);

//where
array(
        'key'=> urldecode('secret in urlencode'),
        'cipher' => MCRYPT_RIJNDAEL_128,
        'mode'   => MCRYPT_MODE_CBC,
       ),

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...