module OpenSSL::PKey
Алгоритмы асимметричного шифрования с открытым ключом
Алгоритмы асимметричного шифрования с открытым ключом решают задачу создания и обмена секретными ключами для шифрования и расшифрования сообщений. Ключ в таком алгоритме состоит из двух частей: открытого ключа, который можно распространять, и закрытого ключа, который необходимо хранить в секрете.
Сообщения, зашифрованные открытым ключом, могут быть расшифрованы только получателями, у которых есть соответствующий закрытый ключ. Поскольку алгоритмы с открытым ключом значительно медленнее симметричных алгоритмов (см. OpenSSL::Cipher), их часто используют для установления общего симметричного ключа между двумя сторонами, располагающими открытыми ключами друг друга.
Асимметричные алгоритмы обладают множеством полезных возможностей, применяемых в самых разных областях. Очень распространённый способ применения — создание и проверка цифровых подписей. Для подписания документа подписывающая сторона обычно использует алгоритм хеширования сообщений (см. OpenSSL::Digest), чтобы вычислить хеш документа, который затем шифруется (то есть подписывается) закрытым ключом. Любой обладатель открытого ключа может проверить подпись: самостоятельно вычислить хеш исходного документа, расшифровать подпись открытым ключом подписавшей стороны и сравнить результат с ранее вычисленным хешем. Подпись действительна тогда и только тогда, когда расшифрованная подпись совпадает с этим хешем.
Модуль PKey поддерживает три популярных алгоритма с открытым и закрытым ключами:
-
Криптография на эллиптических кривых (
OpenSSL::PKey::EC)
Каждая из этих реализаций фактически является подклассом абстрактного класса PKey, предоставляющего интерфейс для поддержки цифровых подписей в виде методов PKey#sign и PKey#verify.
Обмен ключами по протоколу Диффи — Хеллмана
Наконец, PKey также поддерживает OpenSSL::PKey::DH — реализацию протокола обмена ключами Диффи — Хеллмана, основанного на дискретных логарифмах в конечных полях; на той же основе построен DSA. Протокол Диффи — Хеллмана можно использовать для обмена (симметричными) ключами по незащищённым каналам без необходимости предварительно обмениваться какими-либо данными. Поскольку для обеспечения безопасности DH требуются относительно длинные «открытые ключи» (то есть части, которые передаются между участниками в открытом виде), DH работает довольно медленно. Если для вас важнее безопасность или скорость, OpenSSL::PKey::EC предлагает другую реализацию протокола Диффи — Хеллмана.
Константы
- DHError
-
Псевдоним
PKeyError. До версии 4.0.0 этот класс был подклассомPKeyError. - DSAError
-
Псевдоним
PKeyError. До версии 4.0.0 этот класс был подклассомPKeyError. - ECError
-
Псевдоним
PKeyError. До версии 4.0.0 этот класс был подклассомPKeyError. - RSAError
-
Псевдоним
PKeyError. До версии 4.0.0 этот класс был подклассомPKeyError.
Открытые методы класса
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...
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
static VALUE
ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)
{
EVP_PKEY *pkey;
size_t keylen;
StringValue(key);
keylen = RSTRING_LEN(key);
#ifdef OSSL_USE_PROVIDER
pkey = EVP_PKEY_new_raw_private_key_ex(NULL, StringValueCStr(type), NULL,
(unsigned char *)RSTRING_PTR(key),
keylen);
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key_ex");
#else
int pkey_id = lookup_pkey_type(type);
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");
#endif
return ossl_pkey_wrap(pkey);
} См. документацию OpenSSL по EVP_PKEY_new_raw_private_key()
static VALUE
ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)
{
EVP_PKEY *pkey;
size_t keylen;
StringValue(key);
keylen = RSTRING_LEN(key);
#ifdef OSSL_USE_PROVIDER
pkey = EVP_PKEY_new_raw_public_key_ex(NULL, StringValueCStr(type), NULL,
(unsigned char *)RSTRING_PTR(key),
keylen);
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key_ex");
#else
int pkey_id = lookup_pkey_type(type);
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");
#endif
return ossl_pkey_wrap(pkey);
} См. документацию OpenSSL по EVP_PKEY_new_raw_public_key()
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_wrap(pkey);
} Читает строку в кодировке DER или PEM из string либо io и возвращает экземпляр соответствующего класса PKey.
Параметры
-
string — строка в кодировке DER или PEM, содержащая произвольный закрытый или открытый ключ.
-
io — экземпляр
IO, содержащий произвольный закрытый или открытый ключ в кодировке DER или PEM. -
pwd — необязательный пароль на случай, если string или io содержит зашифрованный ресурс PEM.
Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.