class OpenSSL::PKey::DSA
DSA, алгоритм цифровой подписи, определён в стандарте NIST FIPS 186-3. Это асимметричный алгоритм с открытым ключом, который можно использовать, например, подобно RSA.
Открытые методы класса
# File ext/openssl/lib/openssl/pkey.rb, line 199
def generate(size, &blk)
# FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224),
# (2048,256), and (3072,256).
#
# q size is derived here with compatibility with
# DSA_generator_parameters_ex() which previous versions of ruby/openssl
# used to call.
qsize = size >= 2048 ? 256 : 160
dsaparams = OpenSSL::PKey.generate_parameters("DSA", {
"dsa_paramgen_bits" => size,
"dsa_paramgen_q_bits" => qsize,
}, &blk)
OpenSSL::PKey.generate_key(dsaparams)
end Создаёт экземпляр DSA, генерируя с нуля пару закрытого и открытого ключей.
См. также OpenSSL::PKey.generate_parameters и OpenSSL::PKey.generate_key.
size-
Требуемый размер ключа в битах.
static VALUE
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
BIO *in = NULL;
VALUE arg, pass;
int type;
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
if (pkey)
rb_raise(rb_eTypeError, "pkey already initialized");
/* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
rb_scan_args(argc, argv, "02", &arg, &pass);
if (argc == 0) {
#ifdef OSSL_HAVE_IMMUTABLE_PKEY
rb_raise(rb_eArgError, "OpenSSL::PKey::DSA.new cannot be called " \
"without arguments; pkeys are immutable with OpenSSL 3.0");
#else
dsa = DSA_new();
if (!dsa)
ossl_raise(ePKeyError, "DSA_new");
goto legacy;
#endif
}
pass = ossl_pem_passwd_value(pass);
arg = ossl_to_der_if_possible(arg);
in = ossl_obj2bio(&arg);
/* DER-encoded DSAPublicKey format isn't supported by the generic routine */
dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey,
PEM_STRING_DSA_PUBLIC,
in, NULL, NULL, NULL);
if (dsa)
goto legacy;
OSSL_BIO_reset(in);
pkey = ossl_pkey_read_generic(in, pass);
BIO_free(in);
if (!pkey)
ossl_raise(ePKeyError, "Neither PUB key nor PRIV key");
type = EVP_PKEY_base_id(pkey);
if (type != EVP_PKEY_DSA) {
EVP_PKEY_free(pkey);
rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type));
}
RTYPEDDATA_DATA(self) = pkey;
return self;
legacy:
BIO_free(in);
pkey = EVP_PKEY_new();
if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) {
EVP_PKEY_free(pkey);
DSA_free(dsa);
ossl_raise(ePKeyError, "EVP_PKEY_assign_DSA");
}
RTYPEDDATA_DATA(self) = pkey;
return self;
} Создаёт экземпляр DSA, считывая существующий ключ из string.
Если метод вызван без аргументов, создаётся новый экземпляр без заданных компонентов ключа. Их можно задать по отдельности с помощью set_pqg и set_key. Эта форма несовместима с OpenSSL версии 3.0 и более поздних.
Если метод вызван с аргументом типа String, выполняется попытка разобрать его как ключ DSA в формате DER или PEM. См. также OpenSSL::PKey.read, который может считывать ключи любых типов.
Если метод вызван с числом, генерируются случайные параметры и пара ключей. Эта форма является псевдонимом DSA.generate.
string-
String, содержащая ключ в формате DER или PEM. pass-
String, содержащая необязательный пароль. size-
См.
DSA.generate.
Примеры:
p OpenSSL::PKey::DSA.new(1024)
#=> #<OpenSSL::PKey::DSA:0x000055a8d6025bf0 oid=DSA>
p OpenSSL::PKey::DSA.new(File.read('dsa.pem'))
#=> #<OpenSSL::PKey::DSA:0x000055555d6b8110 oid=DSA>
p OpenSSL::PKey::DSA.new(File.read('dsa.pem'), 'mypassword')
#=> #<OpenSSL::PKey::DSA:0x0000556f973c40b8 oid=DSA>
Открытые методы экземпляра
static VALUE
ossl_dsa_export(int argc, VALUE *argv, VALUE self)
{
OSSL_3_const DSA *dsa;
GetDSA(self, dsa);
if (DSA_HAS_PRIVATE(dsa))
return ossl_pkey_export_traditional(argc, argv, self, 0);
else
return ossl_pkey_export_spki(self, 0);
} Сериализует закрытый или открытый ключ в формате PEM.
- Если ключ содержит только компоненты открытого ключа
-
Сериализует его в формате X.509 SubjectPublicKeyInfo. Параметры cipher и password игнорируются.
Ключ в формате PEM будет выглядеть так:
-----BEGIN PUBLIC KEY----- [...] -----END PUBLIC KEY-----
Вместо этого можно использовать
public_to_pem. Этот метод сериализует ключ в формате X.509 SubjectPublicKeyInfo независимо от того, является ли он открытым или закрытым. - Если ключ содержит компоненты закрытого ключа и параметры не заданы
-
Сериализует его в традиционном формате OpenSSL DSAPrivateKey.
Ключ в формате PEM будет выглядеть так:
-----BEGIN DSA PRIVATE KEY----- [...] -----END DSA PRIVATE KEY-----
- Если ключ содержит компоненты закрытого ключа и заданы cipher и password
-
Сериализует его в традиционном формате OpenSSL DSAPrivateKey и шифрует в традиционном формате шифрования PEM в OpenSSL. cipher должен быть названием шифра, распознаваемым методом
OpenSSL::Cipher.new, или экземпляромOpenSSL::Cipher.Зашифрованный ключ в формате PEM будет выглядеть так:
-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 [...] -----END DSA PRIVATE KEY-----
Обратите внимание: для получения ключа шифрования в этом формате используется MD5, поэтому он недоступен в системах, соответствующих требованиям FIPS.
Этот метод сохранён для обеспечения совместимости. Его следует использовать только в случаях, когда требуется традиционный нестандартный формат OpenSSL.
Вместо этого можно использовать public_to_pem (X.509 SubjectPublicKeyInfo) или private_to_pem (PKCS #8 PrivateKeyInfo или EncryptedPrivateKeyInfo).
# File ext/openssl/lib/openssl/pkey.rb, line 181
def params
%w{p q g pub_key priv_key}.map { |name|
[name, send(name)]
}.to_h
end Сохраняет все параметры ключа в Hash.
Хеш содержит ключи ‘p’, ‘q’, ‘g’, ‘pub_key’ и ‘priv_key’.
static VALUE
ossl_dsa_is_private(VALUE self)
{
OSSL_3_const DSA *dsa;
GetDSA(self, dsa);
return DSA_PRIVATE(self, dsa) ? Qtrue : Qfalse;
} Показывает, связан ли с этим экземпляром DSA закрытый ключ. Закрытый ключ можно получить с помощью DSA#private_key.
static VALUE
ossl_dsa_is_public(VALUE self)
{
const DSA *dsa;
const BIGNUM *bn;
GetDSA(self, dsa);
DSA_get0_key(dsa, &bn, NULL);
return bn ? Qtrue : Qfalse;
} Показывает, связан ли с этим экземпляром DSA открытый ключ. Открытый ключ можно получить с помощью DSA#public_key.
# File ext/openssl/lib/openssl/pkey.rb, line 171 def public_key OpenSSL::PKey.read(public_to_der) end
Возвращает новый экземпляр DSA, содержащий только параметры DSA и открытый ключ.
Этот метод предоставлен для обратной совместимости. В большинстве случаев вызывать его не требуется.
Чтобы сериализовать открытый ключ в формате PEM или DER X.509 SubjectPublicKeyInfo, см. PKey#public_to_pem и PKey#public_to_der.
Задаёт pub_key и priv_key для экземпляра DSA. Значение priv_key может быть nil.
Задаёт p, q, g для экземпляра DSA.
# File ext/openssl/lib/openssl/pkey.rb, line 250 def syssign(string) q or raise PKeyError, "incomplete DSA" private? or raise PKeyError, "Private DSA key needed!" sign_raw(nil, string) end
Вычисляет и возвращает подпись DSA для string, где string должно быть уже вычисленным дайджестом исходных входных данных. Подпись создаётся с помощью закрытого ключа этого экземпляра DSA.
Устарел в версии 3.0. Вместо него рекомендуется использовать PKey::PKey#sign_raw и PKey::PKey#verify_raw.
string-
Дайджест исходных входных данных, которые требуется подписать.
Пример:
dsa = OpenSSL::PKey::DSA.new(2048)
doc = "Sign me"
digest = OpenSSL::Digest.digest('SHA1', doc)
# With legacy #syssign and #sysverify:
sig = dsa.syssign(digest)
p dsa.sysverify(digest, sig) #=> true
# With #sign_raw and #verify_raw:
sig = dsa.sign_raw(nil, digest)
p dsa.verify_raw(nil, sig, digest) #=> true
# File ext/openssl/lib/openssl/pkey.rb, line 269 def sysverify(digest, sig) verify_raw(nil, sig, digest) end
Проверяет, является ли подпись действительной для заданного дайджеста сообщения. Для этого sig проверяется с помощью открытого ключа этого экземпляра DSA.
Устарел в версии 3.0. Вместо него рекомендуется использовать PKey::PKey#sign_raw и PKey::PKey#verify_raw.
digest-
Дайджест исходных входных данных, которые требуется подписать.
sig-
Значение подписи DSA.
static VALUE
ossl_dsa_to_der(VALUE self)
{
OSSL_3_const DSA *dsa;
GetDSA(self, dsa);
if (DSA_HAS_PRIVATE(dsa))
return ossl_pkey_export_traditional(0, NULL, self, 1);
else
return ossl_pkey_export_spki(self, 1);
} Сериализует закрытый или открытый ключ в формате DER.
Подробности см. в описании to_pem.
Этот метод сохранён для обеспечения совместимости. Его следует использовать только в случаях, когда требуется традиционный нестандартный формат OpenSSL.
Вместо него рекомендуется использовать public_to_der или private_to_der.
Сериализует закрытый или открытый ключ в формате PEM.
- Если ключ содержит только компоненты открытого ключа
-
Сериализует его в формате X.509 SubjectPublicKeyInfo. Параметры cipher и password игнорируются.
Ключ в формате PEM будет выглядеть так:
-----BEGIN PUBLIC KEY----- [...] -----END PUBLIC KEY-----
Вместо этого можно использовать
public_to_pem. Этот метод сериализует ключ в формате X.509 SubjectPublicKeyInfo независимо от того, является ли он открытым или закрытым. - Если ключ содержит компоненты закрытого ключа и параметры не заданы
-
Сериализует его в традиционном формате OpenSSL DSAPrivateKey.
Ключ в формате PEM будет выглядеть так:
-----BEGIN DSA PRIVATE KEY----- [...] -----END DSA PRIVATE KEY-----
- Если ключ содержит компоненты закрытого ключа и заданы cipher и password
-
Сериализует его в традиционном формате OpenSSL DSAPrivateKey и шифрует в традиционном формате шифрования PEM в OpenSSL. cipher должен быть названием шифра, распознаваемым методом
OpenSSL::Cipher.new, или экземпляромOpenSSL::Cipher.Зашифрованный ключ в формате PEM будет выглядеть так:
-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 [...] -----END DSA PRIVATE KEY-----
Обратите внимание: для получения ключа шифрования в этом формате используется MD5, поэтому он недоступен в системах, соответствующих требованиям FIPS.
Этот метод сохранён для обеспечения совместимости. Его следует использовать только в случаях, когда требуется традиционный нестандартный формат OpenSSL.
Вместо этого можно использовать public_to_pem (X.509 SubjectPublicKeyInfo) или private_to_pem (PKCS #8 PrivateKeyInfo или EncryptedPrivateKeyInfo).
Сериализует закрытый или открытый ключ в формате PEM.
- Если ключ содержит только компоненты открытого ключа
-
Сериализует его в формате X.509 SubjectPublicKeyInfo. Параметры cipher и password игнорируются.
Ключ в формате PEM будет выглядеть так:
-----BEGIN PUBLIC KEY----- [...] -----END PUBLIC KEY-----
Вместо этого можно использовать
public_to_pem. Этот метод сериализует ключ в формате X.509 SubjectPublicKeyInfo независимо от того, является ли он открытым или закрытым. - Если ключ содержит компоненты закрытого ключа и параметры не заданы
-
Сериализует его в традиционном формате OpenSSL DSAPrivateKey.
Ключ в формате PEM будет выглядеть так:
-----BEGIN DSA PRIVATE KEY----- [...] -----END DSA PRIVATE KEY-----
- Если ключ содержит компоненты закрытого ключа и заданы cipher и password
-
Сериализует его в традиционном формате OpenSSL DSAPrivateKey и шифрует в традиционном формате шифрования PEM в OpenSSL. cipher должен быть названием шифра, распознаваемым методом
OpenSSL::Cipher.new, или экземпляромOpenSSL::Cipher.Зашифрованный ключ в формате PEM будет выглядеть так:
-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 [...] -----END DSA PRIVATE KEY-----
Обратите внимание: для получения ключа шифрования в этом формате используется MD5, поэтому он недоступен в системах, соответствующих требованиям FIPS.
Этот метод сохранён для обеспечения совместимости. Его следует использовать только в случаях, когда требуется традиционный нестандартный формат OpenSSL.
Вместо этого можно использовать public_to_pem (X.509 SubjectPublicKeyInfo) или private_to_pem (PKCS #8 PrivateKeyInfo или EncryptedPrivateKeyInfo).
Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.