класс OpenSSL::PKey::DSA
DSA, алгоритм цифровой подписи, определен в стандарте NIST FIPS 186-3. Это асимметричный алгоритм с открытым ключом, который может использоваться аналогично, например, RSA.
Публичные методы класса
static VALUE
ossl_dsa_s_generate(VALUE klass, VALUE size)
{
DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */
VALUE obj = dsa_instance(klass, dsa);
if (obj == Qfalse) {
DSA_free(dsa);
ossl_raise(eDSAError, NULL);
}
return obj;
} Создает новый экземпляр DSA, сгенерировав пару открытого и закрытого ключей с нуля.
Параметры
-
size — целое число, представляющее желаемый размер ключа.
static VALUE
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
BIO *in;
VALUE arg, pass;
GetPKey(self, pkey);
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
dsa = DSA_new();
}
else if (RB_INTEGER_TYPE_P(arg)) {
if (!(dsa = dsa_generate(NUM2INT(arg)))) {
ossl_raise(eDSAError, NULL);
}
}
else {
pass = ossl_pem_passwd_value(pass);
arg = ossl_to_der_if_possible(arg);
in = ossl_obj2bio(&arg);
dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
if (!dsa) {
OSSL_BIO_reset(in);
dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
}
if (!dsa) {
OSSL_BIO_reset(in);
dsa = d2i_DSAPrivateKey_bio(in, NULL);
}
if (!dsa) {
OSSL_BIO_reset(in);
dsa = d2i_DSA_PUBKEY_bio(in, NULL);
}
if (!dsa) {
OSSL_BIO_reset(in);
#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
(d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u))
dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
#undef PEM_read_bio_DSAPublicKey
}
BIO_free(in);
if (!dsa) {
ossl_clear_error();
ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
}
}
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
DSA_free(dsa);
ossl_raise(eDSAError, NULL);
}
return self;
} Создает новый экземпляр DSA, прочитав существующий ключ из string.
Параметры
-
size — целое число, представляющее желаемый размер ключа.
-
string содержит закодированный ключ в формате DER или PEM.
-
pass — строка, содержащая необязательный пароль.
Примеры
DSA.new -> dsa
DSA.new(1024) -> dsa
DSA.new(File.read('dsa.pem')) -> dsa
DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa Публичные методы экземпляра
static VALUE
ossl_dsa_export(int argc, VALUE *argv, VALUE self)
{
DSA *dsa;
BIO *out;
const EVP_CIPHER *ciph = NULL;
VALUE cipher, pass, str;
GetDSA(self, dsa);
rb_scan_args(argc, argv, "02", &cipher, &pass);
if (!NIL_P(cipher)) {
ciph = ossl_evp_get_cipherbyname(cipher);
pass = ossl_pem_passwd_value(pass);
}
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (DSA_HAS_PRIVATE(dsa)) {
if (!PEM_write_bio_DSAPrivateKey(out, dsa, ciph, NULL, 0,
ossl_pem_passwd_cb, (void *)pass)){
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
} else {
if (!PEM_write_bio_DSA_PUBKEY(out, dsa)) {
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
}
str = ossl_membio2str(out);
return str;
} Кодирует этот DSA в его PEM-кодировке.
Параметры
-
cipher —
OpenSSL::Cipher. -
password — строка, содержащая ваш пароль.
Примеры
DSA.to_pem -> aString DSA.to_pem(cipher, 'mypassword') -> aString
static VALUE
ossl_dsa_initialize_copy(VALUE self, VALUE other)
{
EVP_PKEY *pkey;
DSA *dsa, *dsa_new;
GetPKey(self, pkey);
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
ossl_raise(eDSAError, "DSA already initialized");
GetDSA(other, dsa);
dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa);
if (!dsa_new)
ossl_raise(eDSAError, "ASN1_dup");
EVP_PKEY_assign_DSA(pkey, dsa_new);
return self;
} static VALUE
ossl_dsa_get_params(VALUE self)
{
DSA *dsa;
VALUE hash;
const BIGNUM *p, *q, *g, *pub_key, *priv_key;
GetDSA(self, dsa);
DSA_get0_pqg(dsa, &p, &q, &g);
DSA_get0_key(dsa, &pub_key, &priv_key);
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));
return hash;
} Сохраняет все параметры ключа в хэш. НЕБЕЗОПАСНО: СВЯЗАННАЯ ИНФОРМАЦИЯ МОЖЕТ БЫТЬ РАСКРЫТА!!! Не используйте :-)) (Это ваш выбор).
static VALUE
ossl_dsa_is_private(VALUE self)
{
DSA *dsa;
GetDSA(self, dsa);
return DSA_PRIVATE(self, dsa) ? Qtrue : Qfalse;
} Указывает, имеет ли этот экземпляр DSA связанный с ним закрытый ключ или нет. Закрытый ключ можно получить с помощью DSA#private_key.
static VALUE
ossl_dsa_is_public(VALUE self)
{
DSA *dsa;
const BIGNUM *bn;
GetDSA(self, dsa);
DSA_get0_key(dsa, &bn, NULL);
return bn ? Qtrue : Qfalse;
} Указывает, имеет ли этот экземпляр DSA связанный с ним открытый ключ или нет. Открытый ключ можно получить с помощью DSA#public_key.
static VALUE
ossl_dsa_to_public_key(VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
VALUE obj;
GetPKeyDSA(self, pkey);
/* err check performed by dsa_instance */
#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \
(i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
#undef DSAPublicKey_dup
obj = dsa_instance(rb_obj_class(self), dsa);
if (obj == Qfalse) {
DSA_free(dsa);
ossl_raise(eDSAError, NULL);
}
return obj;
} Возвращает новый экземпляр DSA, который содержит только информацию об открытом ключе. Если текущий экземпляр также имеет информацию о закрытом ключе, она больше не будет присутствовать в новом экземпляре. Эта функция полезна для публикации информации об открытом ключе без раскрытия любой из информации о закрытом ключе.
Пример
dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information pub_key = dsa.public_key # has only the public part available pub_key_der = pub_key.to_der # it's safe to publish this
Устанавливает pub_key и priv_key для экземпляра DSA. priv_key может быть nil.
Устанавливает p, q, g для экземпляра DSA.
static VALUE
ossl_dsa_sign(VALUE self, VALUE data)
{
DSA *dsa;
const BIGNUM *dsa_q;
unsigned int buf_len;
VALUE str;
GetDSA(self, dsa);
DSA_get0_pqg(dsa, NULL, &dsa_q, NULL);
if (!dsa_q)
ossl_raise(eDSAError, "incomplete DSA");
if (!DSA_PRIVATE(self, dsa))
ossl_raise(eDSAError, "Private DSA key needed!");
StringValue(data);
str = rb_str_new(0, DSA_size(dsa));
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
(unsigned char *)RSTRING_PTR(str),
&buf_len, dsa)) { /* type is ignored (0) */
ossl_raise(eDSAError, NULL);
}
rb_str_set_len(str, buf_len);
return str;
} Вычисляет и возвращает подпись DSA для string, где string предполагается, что это уже вычисленный дайджест сообщения исходных входных данных. Подпись выдается с использованием закрытого ключа этого экземпляра DSA.
Параметры
-
string — дайджест сообщения исходных входных данных, подлежащих подписи.
Пример
dsa = OpenSSL::PKey::DSA.new(2048)
doc = "Sign me"
digest = OpenSSL::Digest.digest('SHA1', doc)
sig = dsa.syssign(digest)
static VALUE
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
{
DSA *dsa;
int ret;
GetDSA(self, dsa);
StringValue(digest);
StringValue(sig);
/* type is ignored (0) */
ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), dsa);
if (ret < 0) {
ossl_raise(eDSAError, NULL);
}
else if (ret == 1) {
return Qtrue;
}
return Qfalse;
} Проверяет, является ли подпись действительной, принимая во внимание входной дайджест сообщения. Это делается путем проверки sig с использованием открытого ключа этого экземпляра DSA.
Параметры
-
digest — дайджест сообщения исходных входных данных, подлежащих подписи
-
sig — значение подписи
DSA
Пример
dsa = OpenSSL::PKey::DSA.new(2048)
doc = "Sign me"
digest = OpenSSL::Digest.digest('SHA1', doc)
sig = dsa.syssign(digest)
puts dsa.sysverify(digest, sig) # => true
static VALUE
ossl_dsa_to_der(VALUE self)
{
DSA *dsa;
int (*i2d_func)(DSA *, unsigned char **);
unsigned char *p;
long len;
VALUE str;
GetDSA(self, dsa);
if(DSA_HAS_PRIVATE(dsa))
i2d_func = (int (*)(DSA *,unsigned char **))i2d_DSAPrivateKey;
else
i2d_func = i2d_DSA_PUBKEY;
if((len = i2d_func(dsa, NULL)) <= 0)
ossl_raise(eDSAError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_func(dsa, &p) < 0)
ossl_raise(eDSAError, NULL);
ossl_str_adjust(str, p);
return str;
} Кодирует этот DSA в его DER-кодировке.
Кодирует этот DSA в его PEM-кодировке.
Параметры
-
cipher —
OpenSSL::Cipher. -
password — строка, содержащая ваш пароль.
Примеры
DSA.to_pem -> aString DSA.to_pem(cipher, 'mypassword') -> aString
Кодирует этот DSA в его PEM-кодировке.
Параметры
-
cipher —
OpenSSL::Cipher. -
password — строка, содержащая ваш пароль.
Примеры
DSA.to_pem -> aString DSA.to_pem(cipher, 'mypassword') -> aString
static VALUE
ossl_dsa_to_text(VALUE self)
{
DSA *dsa;
BIO *out;
VALUE str;
GetDSA(self, dsa);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (!DSA_print(out, dsa, 0)) { /* offset = 0 */
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
str = ossl_membio2str(out);
return str;
} Выводит все параметры ключа в буфер. НЕБЕЗОПАСНО: СВЯЗАННАЯ ИНФОРМАЦИЯ МОЖЕТ БЫТЬ РАСКРЫТА!!! Не используйте :-)) (Это ваш выбор).
Ruby Core © 1993–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.