Spec-Zone.ru › Ruby 2.3

class 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 34
def self.digest(name, data)
  super(data, name)
end

Возвращает data хэш, вычисленный с помощью name 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 так, что любые выполненные #update отменяются, и Digest устанавливается в начальное состояние.

update(string) → строка Показать исходный код
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