Spec-Zone.ru › Ruby 3.3

модуль OpenSSL::PKey

Асимметричные алгоритмы с открытым ключом

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

Сообщения, зашифрованные открытым ключом, могут быть расшифрованы только получателями, у которых есть соответствующий закрытый ключ. Поскольку алгоритмы с открытым ключом значительно медленнее, чем алгоритмы с симметричным ключом (см. OpenSSL::Cipher), они часто используются для установления симметричного ключа между двумя сторонами, у которых есть открытый ключ друг друга.

Асимметричные алгоритмы предлагают множество полезных функций, используемых в различных областях. Очень распространённым применением является создание и проверка цифровых подписей. Для подписи документа подписывающий обычно использует алгоритм дайджеста сообщения (см. OpenSSL::Digest), чтобы вычислить дайджест документа, который затем шифруется (т. е. подписывается) с помощью закрытого ключа. Любой, у кого есть открытый ключ, может затем проверить подпись, вычислив дайджест сообщения исходного документа самостоятельно, расшифровав подпись с помощью открытого ключа подписывающего лица и сравнив результат с дайджестом сообщения, который он вычислил ранее. Подпись является действительной только в том случае, если расшифрованная подпись равна этому дайджесту сообщения.

Модуль PKey поддерживает три популярных алгоритма с открытым/закрытым ключом:

  • RSA (OpenSSL::PKey::RSA)

  • DSA (OpenSSL::PKey::DSA)

  • Криптография эллиптических кривых (OpenSSL::PKey::EC)

Каждая из этих реализаций фактически является подклассом абстрактного класса PKey, который предлагает интерфейс для поддержки цифровых подписей в виде методов PKey#sign и PKey#verify.

Обмен ключами Диффи-Хеллмана

Наконец, PKey также включает OpenSSL::PKey::DH, реализацию протокола обмена ключами Диффи-Хеллмана, основанную на дискретных логарифмах в конечных полях, на той же основе, что и DSA. Протокол Диффи-Хеллмана может использоваться для обмена (симметричными) ключами по небезопасным каналам без предварительного совместного знания между участвующими сторонами. Поскольку безопасность DH требует относительно длинных «открытых ключей» (т. е. части, которая открыто передаётся между участниками), DH обычно довольно медленный. Если для вас первостепенны безопасность или скорость, OpenSSL::PKey::EC предлагает другую реализацию протокола Диффи-Хеллмана.

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

OpenSSL::PKey.generate_key(algo_name [, options]) → pkey Показать исходный код
OpenSSL::PKey.generate_key(pkey [, options]) → pkey
static VALUE
ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self)
{
    return pkey_generate(argc, argv, self, 0);
}

Генерирует новый ключ (пару).

Если в качестве первого аргумента передаётся String, генерируется новый случайный ключ для алгоритма, указанного по имени, как и в ::generate_parameters. Если вместо этого передаётся OpenSSL::PKey::PKey, генерируется новый случайный ключ для того же алгоритма, что и у ключа, используя параметры, содержащиеся в ключе.

Подробности параметров options и переданного блока см. в ::generate_parameters.

Пример

pkey_params = OpenSSL::PKey.generate_parameters("DSA", "dsa_paramgen_bits" => 2048)
pkey_params.priv_key #=> nil
pkey = OpenSSL::PKey.generate_key(pkey_params)
pkey.priv_key #=> #<OpenSSL::BN 6277...
OpenSSL::PKey.generate_parameters(algo_name [, options]) → pkey Показать исходный код
static VALUE
ossl_pkey_s_generate_parameters(int argc, VALUE *argv, VALUE self)
{
    return pkey_generate(argc, argv, self, 1);
}

Генерирует новые параметры для алгоритма. algo_name — это String, представляющий алгоритм. Необязательный аргумент options — это Hash, определяющий параметры, специфичные для алгоритма. Порядок параметров может иметь значение.

Можно необязательно передать блок. Значение аргументов, передаваемых в блок, варьируется в зависимости от реализации алгоритма. Блок может вызываться один раз или несколько раз, или даже не вызываться.

Подробности поддерживаемых параметров см. в документации для утилиты командной строки «openssl genpkey».

Пример

pkey = OpenSSL::PKey.generate_parameters("DSA", "dsa_paramgen_bits" => 2048)
p pkey.p.num_bits #=> 2048
OpenSSL::PKey.new_raw_private_key(algo, string) → PKey Показать исходный код
static VALUE
ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)
{
    EVP_PKEY *pkey;
    const EVP_PKEY_ASN1_METHOD *ameth;
    int pkey_id;
    size_t keylen;

    StringValue(type);
    StringValue(key);
    ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
    if (!ameth)
        ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
    EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);

    keylen = RSTRING_LEN(key);

    pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
    if (!pkey)
        ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key");

    return ossl_pkey_new(pkey);
}

См. документацию OpenSSL для EVP_PKEY_new_raw_private_key()

OpenSSL::PKey.new_raw_public_key(algo, string) → PKey Показать исходный код
static VALUE
ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)
{
    EVP_PKEY *pkey;
    const EVP_PKEY_ASN1_METHOD *ameth;
    int pkey_id;
    size_t keylen;

    StringValue(type);
    StringValue(key);
    ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
    if (!ameth)
        ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
    EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);

    keylen = RSTRING_LEN(key);

    pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
    if (!pkey)
        ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key");

    return ossl_pkey_new(pkey);
}

См. документацию OpenSSL для EVP_PKEY_new_raw_public_key()

OpenSSL::PKey.read(string [, pwd ]) → PKey Показать исходный код
OpenSSL::PKey.read(io [, pwd ]) → PKey
static VALUE
ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    BIO *bio;
    VALUE data, pass;

    rb_scan_args(argc, argv, "11", &data, &pass);
    bio = ossl_obj2bio(&data);
    pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass));
    BIO_free(bio);
    if (!pkey)
        ossl_raise(ePKeyError, "Could not parse PKey");
    return ossl_pkey_new(pkey);
}

Читает закодированную в DER или PEM строку из string или io и возвращает экземпляр соответствующего класса PKey.

Параметры

  • string — это строка DER или PEM, содержащая произвольный закрытый или открытый ключ.

  • io — это экземпляр IO, содержащий закодированный в DER или PEM произвольный закрытый или открытый ключ.

  • pwd — это необязательный пароль в случае, если string или io — это зашифрованный PEM-ресурс.

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