Spec-Zone.ru › Ruby 2.2

класс OpenSSL::Digest

Родитель:
OpenSSL::Digest::Class

OpenSSL::Digest позволяет вычислять хеши произвольных данных, которые являются криптографически безопасными, т.е. Digest реализует безопасную одностороннюю функцию.

Односторонние функции обладают некоторыми полезными свойствами. Например, при двух различных входных данных вероятность того, что оба дадут одинаковый выход, очень мала. В сочетании с тем, что каждый алгоритм хеширования имеет выходной размер фиксированной длины всего в несколько байтов, хеши часто используются для создания уникальных идентификаторов произвольных данных. Типичный пример — создание уникального идентификатора для двоичных документов, хранящихся в базе данных.

Еще одной полезной характеристикой односторонних функций (и, следовательно, названием) является то, что, зная хеш, нет никакой информации о исходных данных, которые его породили, т.е. единственный способ идентифицировать исходный вход — «перебор» всех возможных комбинаций входных данных.

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

Среди поддерживаемых алгоритмов хеширования:

  • SHA, SHA1, SHA224, SHA256, SHA384 и SHA512

  • MD2, MD4, MDC2 и MD5

  • RIPEMD160

  • DSS, DSS1 (Псевдоалгоритмы для использования в подписях DSA. DSS эквивалентен SHA, а DSS1 — SHA1)

Для каждого из этих алгоритмов существует подкласс Digest, который можно создать так же просто, как, например,

digest = OpenSSL::Digest::SHA1.new

Сопоставление класса Digest и sn/ln

sn (краткие имена) и ln (полные имена) определены в <openssl/object.h> и <openssl/obj_mac.h>. Они представляют собой текстовые представления идентификаторов OBJECT ASN.1. Каждый поддерживаемый алгоритм хеширования имеет связанный с ним идентификатор OBJECT, у которых, в свою очередь, есть краткие и полные имена. Например, идентификатор OBJECT для SHA-1 — 1.3.14.3.2.26, его sn — «SHA1», а ln — «sha1».

MD2

  • sn: MD2

  • ln: md2

MD4

  • sn: MD4

  • ln: md4

MD5

  • sn: MD5

  • ln: md5

SHA

  • sn: SHA

  • ln: SHA

SHA-1

  • sn: SHA1

  • ln: sha1

SHA-224

  • sn: SHA224

  • ln: sha224

SHA-256

  • sn: SHA256

  • ln: sha256

SHA-384

  • sn: SHA384

  • ln: sha384

SHA-512

  • sn: SHA512

  • ln: sha512

«Взлом» алгоритма хеширования означает нарушение его свойств односторонней функции, т.е. создание коллизии или поиск способа получения исходных данных с помощью методов, более эффективных, чем перебор и т.п. Большинство поддерживаемых алгоритмов хеширования можно считать взломанными в этом смысле, даже очень популярные MD5 и SHA1. Если безопасность является для вас наивысшим приоритетом, то, вероятно, вам следует полагаться на SHA224, SHA256, SHA384 или SHA512.

Хеширование файла

data = File.read('document')
sha256 = OpenSSL::Digest::SHA256.new
digest = sha256.digest(data)

Хеширование нескольких кусков данных одновременно

data1 = File.read('file1')
data2 = File.read('file2')
data3 = File.read('file3')
sha256 = OpenSSL::Digest::SHA256.new
sha256 << data1
sha256 << data2
sha256 << data3
digest = sha256.digest

Использование экземпляра Digest

data1 = File.read('file1')
sha256 = OpenSSL::Digest::SHA256.new
digest1 = sha256.digest(data1)

data2 = File.read('file2')
sha256.reset
digest2 = sha256.digest(data2)

Общедоступные методы класса

digest(name, data) Показать исходный код
# File ext/openssl/lib/openssl/digest.rb, line 40
def self.digest(name, data)
  super(data, name)
end

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

Примеры

OpenSSL::Digest.digest("SHA256", "abc")

что эквивалентно:

OpenSSL::Digest::SHA256.digest("abc")
Вызывает метод суперкласса
new(string [, data]) → Digest Показать исходный код
static VALUE
ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_MD_CTX *ctx;
    const EVP_MD *md;
    VALUE type, data;

    rb_scan_args(argc, argv, "11", &type, &data);
    md = GetDigestPtr(type);
    if (!NIL_P(data)) StringValue(data);

    GetDigest(self, ctx);
    if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
        ossl_raise(eDigestError, "Digest initialization failed.");
    }

    if (!NIL_P(data)) return ossl_digest_update(self, data);
    return self;
}

Создает экземпляр Digest на основе string, которое является либо полным (ln), либо коротким (sn) именем поддерживаемого алгоритма хеширования. Если data (строка) предоставлено, оно используется в качестве начального входных данных для экземпляра Digest, т.е.

digest = OpenSSL::Digest.new('sha256', 'digestdata')

равно

digest = OpenSSL::Digest.new('sha256')
digest.update('digestdata')

Пример

digest = OpenSSL::Digest.new('sha1')

Общедоступные методы экземпляра

<<(p1)
Псевдоним для: update
block_length → целое число Показать исходный код
static VALUE
ossl_digest_block_length(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return INT2NUM(EVP_MD_CTX_block_size(ctx));
}

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

Пример

digest = OpenSSL::Digest::SHA1.new
puts digest.block_length # => 64
digest_length → целое число Показать исходный код
static VALUE
ossl_digest_size(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return INT2NUM(EVP_MD_CTX_size(ctx));
}

Возвращает размер вывода хеширования, т.е. длину результата хеширования в байтах.

Пример

digest = OpenSSL::Digest::SHA1.new
puts digest.digest_length # => 20
name → строка Показать исходный код
static VALUE
ossl_digest_name(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));
}

Возвращает sn этого экземпляра Digest.

Пример

digest = OpenSSL::Digest::SHA512.new
puts digest.name # => SHA512
reset → self Показать исходный код
static VALUE
ossl_digest_reset(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);
    if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) {
        ossl_raise(eDigestError, "Digest initialization failed.");
    }

    return self;
}

Сбрасывает Digest в том смысле, что любые выполненные обновления отменяются, и Digest устанавливается в начальное состояние.

update(строка) → строка Показать исходный код
VALUE
ossl_digest_update(VALUE self, VALUE data)
{
    EVP_MD_CTX *ctx;

    StringValue(data);
    GetDigest(self, ctx);
    EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));

    return self;
}

Не каждый хеш может быть вычислен за один проход. Если хеш должен быть вычислен из нескольких последовательных источников, каждый из них может быть передан экземпляру Digest.

Пример

digest = OpenSSL::Digest::SHA256.new
digest.update('First input')
digest << 'Second input' # equivalent to digest.update('Second input')
result = digest.digest
Также алиас для: <<

Приватные методы экземпляра

finish → строка Показать исходный код
static VALUE
ossl_digest_finish(int argc, VALUE *argv, VALUE self)
{
    EVP_MD_CTX *ctx;
    VALUE str;

    rb_scan_args(argc, argv, "01", &str);

    GetDigest(self, ctx);

    if (NIL_P(str)) {
        str = rb_str_new(NULL, EVP_MD_CTX_size(ctx));
    } else {
        StringValue(str);
        rb_str_resize(str, EVP_MD_CTX_size(ctx));
    }

    EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL);

    return str;
}

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