Spec-Zone.ru › Ruby 2.4

модуль OpenSSL::PKCS5

Обеспечивает функциональность шифрования на основе пароля, основанную на PKCS#5. Обычно используется для безопасного вывода симметричных ключей произвольной длины, которые будут использоваться с OpenSSL::Cipher из паролей. Еще один случай использования — хранение паролей: благодаря возможности настраивать сложность вычислений путём увеличения счётчика итераций, вычисления можно искусственно замедлить, чтобы сделать возможные атаки неэффективными.

PKCS5 поддерживает PBKDF2 с основой на HMAC OpenSSL::Digest::SHA1 или произвольным Digest, если поддерживается подлежащая версия OpenSSL (>= 1.0.0).

Параметры

Пароль

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

Соль

Предотвращает атаки, основанные на словарях общих паролей. Это общедоступное значение, которое можно безопасно хранить вместе с паролем (например, если PBKDF2 используется для хранения паролей). Для максимальной безопасности для каждого хранимого пароля должна генерироваться новая случайная соль. В соответствии с PKCS#5 соль должна иметь длину не менее 8 байт.

Счётчик итераций

Позволяет настраивать длительность фактических вычислений. Чем больше счётчик итераций, тем дольше займут вычисления.

Длина ключа

Указывает длину в байтах генерируемого на выходе значения. Обычно длина ключа должна быть больше или равна длине выходных данных подлежащей функции хеширования, в противном случае злоумышленник может просто попробовать перебрать ключ. Согласно PKCS#5, безопасность ограничена длиной выходных данных подлежащей функции хеширования, т. е. безопасность не улучшается, если выбранная длина ключа строго больше длины выходных данных хеширования. Поэтому при использовании PKCS5 для хранения паролей достаточно хранить значения, равные длине выходных данных хеширования; хранение больших значений ничего не даёт.

Примеры

Генерация 128-битного ключа для Cipher (например, AES)

pass = "secret"
salt = OpenSSL::Random.random_bytes(16)
iter = 20000
key_len = 16
key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)

Хранение паролей

pass = "secret"
salt = OpenSSL::Random.random_bytes(16) #store this with the generated value
iter = 20000
digest = OpenSSL::Digest::SHA256.new
len = digest.digest_length
#the final value to be stored
value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest)

Важное примечание о проверке паролей

При сравнении паролей, предоставленных пользователем, с ранее сохранёнными значениями распространённой ошибкой является сравнение двух значений с помощью “==”. Обычно “==” прерывает выполнение при оценке, и поэтому уязвим для атак по времени. Правильный способ — использовать метод, который всегда затрачивает одинаковое время при сравнении двух значений, таким образом не раскрывая никакой информации потенциальным злоумышленникам. Для сравнения двух значений можно использовать следующее:

def eql_time_cmp(a, b)
  unless a.length == b.length
    return false
  end
  cmp = b.bytes.to_a
  result = 0
  a.bytes.each_with_index {|c,i|
    result |= c ^ cmp[i]
  }
  result == 0
end

Обратите внимание, что преждевременное возвращение в случае разной длины, как правило, не раскрывает ценной информации — при использовании PKCS#5 длина сравниваемых значений имеет фиксированный размер.

Методы публичного класса

pbkdf2_hmac(pass, salt, iter, keylen, digest) → string Показать исходный код
static VALUE
ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
{
    VALUE str;
    const EVP_MD *md;
    int len = NUM2INT(keylen);

    StringValue(pass);
    StringValue(salt);
    md = GetDigestPtr(digest);

    str = rb_str_new(0, len);

    if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
                          (unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt),
                          NUM2INT(iter), md, len,
                          (unsigned char *)RSTRING_PTR(str)) != 1)
        ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");

    return str;
}

Параметры

  • pass - строка

  • salt - строка — должна иметь длину не менее 8 байт.

  • iter - целое число — должно быть больше 1000. 20000 — лучше.

  • keylen - целое число

  • digest - строка или объект OpenSSL::Digest.

Доступно в OpenSSL >= 1.0.0.

Функции хеширования, отличные от SHA1, могут не поддерживаться другими библиотеками криптографии.

pbkdf2_hmac_sha1(pass, salt, iter, keylen) → string Показать исходный код
static VALUE
ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
{
    VALUE str;
    int len = NUM2INT(keylen);

    StringValue(pass);
    StringValue(salt);

    str = rb_str_new(0, len);

    if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
                               (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
                               len, (unsigned char *)RSTRING_PTR(str)) != 1)
        ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");

    return str;
}

Параметры

  • pass - строка

  • salt - строка — должна иметь длину не менее 8 байт.

  • iter - целое число — должно быть больше 1000. 20000 — лучше.

  • keylen - целое число

Этот метод доступен практически во всех версиях OpenSSL.

Соответствует RFC 2898.

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API