Spec-Zone.ru › Ruby 3.3

класс OpenSSL::Digest

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

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

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

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

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

Вы можете получить список всех поддерживаемых на вашей системе алгоритмов хэширования, выполнив эту команду в вашей консоли:

openssl list -digest-algorithms

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

  • SHA224, SHA256, SHA384, SHA512, SHA512-224 и SHA512-256

  • SHA3-224, SHA3-256, SHA3-384 и SHA3-512

  • BLAKE2s256 и BLAKE2b512

Каждый из этих алгоритмов может быть создан с помощью имени:

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

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

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

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

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

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

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

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

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

Методы класса

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

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

Пример

OpenSSL::Digest.digest("SHA256", "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 = ossl_evp_get_digestbyname(type);
    if (!NIL_P(data)) StringValue(data);

    TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx);
    if (!ctx) {
        RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new();
        if (!ctx)
            ossl_raise(eDigestError, "EVP_MD_CTX_new");
    }

    if (!EVP_DigestInit_ex(ctx, md, NULL))
        ossl_raise(eDigestError, "Digest initialization failed");

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

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

Если data (a String) задано, оно используется в качестве начального входного значения для экземпляра Digest, т.е.

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

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

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

Методы экземпляра

<<
Псевдоним для: 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.new('SHA1')
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.new('SHA1')
puts digest.digest_length # => 20
initialize_copy(p1) Показать исходный код
static VALUE
ossl_digest_copy(VALUE self, VALUE other)
{
    EVP_MD_CTX *ctx1, *ctx2;

    rb_check_frozen(self);
    if (self == other) return self;

    TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx1);
    if (!ctx1) {
        RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new();
        if (!ctx1)
            ossl_raise(eDigestError, "EVP_MD_CTX_new");
    }
    GetDigest(other, ctx2);

    if (!EVP_MD_CTX_copy(ctx1, ctx2)) {
        ossl_raise(eDigestError, NULL);
    }
    return self;
}
name → строка Показать исходный код
static VALUE
ossl_digest_name(VALUE self)
{
    EVP_MD_CTX *ctx;

    GetDigest(self, ctx);

    return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx)));
}

Возвращает короткое имя (sn) этого алгоритма хэширования.

Пример

digest = OpenSSL::Digest.new('SHA512')
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_get0_md(ctx), NULL) != 1) {
        ossl_raise(eDigestError, "Digest initialization failed.");
    }

    return self;
}

Сбрасывает состояние алгоритма хэширования, отменяя любые операции обновления и устанавливая состояние алгоритма в исходное.

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

    StringValue(data);
    GetDigest(self, ctx);

    if (!EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)))
        ossl_raise(eDigestError, "EVP_DigestUpdate");

    return self;
}

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

Пример

digest = OpenSSL::Digest.new('SHA256')
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;
    int out_len;

    GetDigest(self, ctx);
    rb_scan_args(argc, argv, "01", &str);
    out_len = EVP_MD_CTX_size(ctx);

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

    if (!EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL))
        ossl_raise(eDigestError, "EVP_DigestFinal_ex");

    return str;
}

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

Spec-Zone.ru

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