2016-06-23 2 views
2

Используя следующие узловые ЯШ:EVP_DecryptFinal_ex: плохо расшифровывать при использовании Node.js

var crypto = require('crypto'); 
var encrypt = function (input, password, callback) { 
    var m = crypto.createHash('md5'); 
    m.update(password); 
    var key = m.digest('hex'); 

    m = crypto.createHash('md5'); 
    m.update(password + key); 
    var iv = m.digest('hex'); 
    console.log(iv); 

    var data = new Buffer(input, 'utf8').toString('binary'); 

    var cipher = crypto.createCipheriv('aes-256-cbc', key, iv.slice(0,16)); 
    var encrypted = cipher.update(data, 'binary') + cipher.final('binary'); 
    var encoded = new Buffer(encrypted, 'binary').toString('base64'); 
    callback(encoded); 
}; 

var decrypt = function (input, password, callback) { 
    // Convert urlsafe base64 to normal base64 
    input = input.replace(/\-/g, '+').replace(/_/g, '/'); 
    // Convert from base64 to binary string 
    var edata = new Buffer(input, 'base64').toString('binary'); 

    // Create key from password 
    var m = crypto.createHash('md5'); 
    m.update(password); 
    var key = m.digest('hex'); 

    // Create iv from password and key 
    m = crypto.createHash('md5'); 
    m.update(password + key); 
    var iv = m.digest('hex'); 

    // Decipher encrypted data 
    var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv.slice(0,16)); 
    var decrypted = decipher.update(edata, 'binary') + decipher.final('binary'); 
    var plaintext = new Buffer(decrypted, 'binary').toString('utf8'); 

    callback(plaintext); 
}; 

Для выполнения я побежал это:

encrypt("uWeShxRrCKyK4pcs", "secret", function (encoded) { 
    console.log(encoded); 
    decrypt(encoded, "secret", function (output) { 
     console.log(output); 
    }); 
}); 

шифрованной, кажется, работает хорошо, но когда я пытаюсь расшифровать , я получаю следующее сообщение об ошибке:

Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt at Error (native) at Decipheriv.Cipher.final (crypto.js:202:26)

Я довольно новый для криптографии, так что на самом деле не знаю, почему я receivin g эта ошибка. Мне просто нужно исправить это.

+0

1. MD5 shoukld не используется, не защищен и не является простым хэшированием пароля достаточно безопасным. 2. Итерации по HMAC со случайной солью в течение приблизительно 100 мс (соль должна быть сохранена с хешем). Используйте такие функции, как password_hash, PBKDF2, Bcrypt или аналогичные функции. Дело в том, чтобы заставить злоумышленника потратить много времени на поиск паролей грубой силой. См. OWASP (Проект обеспечения безопасности веб-приложений) [Шифрование для хранения паролей] (https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Leverage_an_adaptive_one-way_function). – zaph

+0

Спасибо, но я понятия не имею, как изменить свой код, чтобы сделать это. Я попытаюсь посмотреть на bcrypt. –

+0

Время отладки. Hex сбрасывает ключ и iv на шифрование и дешифрование и проверяет правильность их длины и правильную длину. Ключ AES должен быть 32 байта и iv 16-байтов, точно.Hex сбрасывает зашифрованные сразу же после шифрования и снова непосредственно перед расшифровкой, убедитесь, что они одинаковы. – zaph

ответ

3

Вы смешиваете два разных кодировки. См

cipher.update(data[, input_encoding][, output_encoding])

и

cipher.final([output_encoding])

и теперь посмотрим на

var encrypted = cipher.update(data, 'binary') + cipher.final('binary'); 

, но это должно быть

var encrypted = cipher.update(data, 'binary', 'binary') + cipher.final('binary'); 

Вопрос заключается в том, что cipher.update(data, 'binary') выводит буфер, который автоматически stringifies в a H ex-encoded string вместо «двоичной» -строки.


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

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

  • Пароль имеет низкую энтропию и не может использоваться в качестве ключа. Один вызов MD5 не изменяет этот факт. Предполагается, что ключевой вывод из пароля является медленным, поэтому используйте известную схему, такую ​​как PBKDF2, bcrypt, scrypt или Argon2 (повышающая безопасность) с высоким коэффициентом итерации/коэффициентом затрат. Не забывайте о соли.

  • Аутентификация вашего зашифрованного текста с кодом аутентификации сообщения, таким как HMAC-SHA256, в схеме шифрования-затем-MAC. В противном случае злоумышленник может манипулировать зашифрованными текстами, и вы даже не сможете обнаружить изменения. Первый шаг к потере данных с помощью атаки оскорбления.

Смежные вопросы