class OpenSSL::PKey::DSA
DSA, the Digital Signature Algorithm, is specified in NIST's FIPS 186-3. It is an asymmetric public key algorithm that may be used similarly to, for example, RSA. Please note that for OpenSSL versions prior to 1.0.0 the digest algorithms OpenSSL::Digest::DSS (equivalent to SHA) or OpenSSL::Digest::DSS1 (equivalent to SHA-1) must be used for issuing signatures with a DSA key using OpenSSL::PKey#sign. Starting with OpenSSL 1.0.0, digest algorithms are no longer restricted; any Digest may be used for signing.
Общедоступные методы класса
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;
char *passwd = NULL;
VALUE arg, pass;
GetPKey(self, pkey);
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
dsa = DSA_new();
}
else if (FIXNUM_P(arg)) {
if (!(dsa = dsa_generate(FIX2INT(arg)))) {
ossl_raise(eDSAError, NULL);
}
}
else {
if (!NIL_P(pass)) passwd = StringValuePtr(pass);
arg = ossl_to_der_if_possible(arg);
in = ossl_obj2bio(&arg);
dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
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);
dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
}
BIO_free(in);
if (!dsa) {
ERR_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)
{
EVP_PKEY *pkey;
BIO *out;
const EVP_CIPHER *ciph = NULL;
char *passwd = NULL;
VALUE cipher, pass, str;
GetPKeyDSA(self, pkey);
rb_scan_args(argc, argv, "02", &cipher, &pass);
if (!NIL_P(cipher)) {
ciph = GetCipherPtr(cipher);
if (!NIL_P(pass)) {
StringValue(pass);
if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
passwd = RSTRING_PTR(pass);
}
}
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (DSA_HAS_PRIVATE(pkey->pkey.dsa)) {
if (!PEM_write_bio_DSAPrivateKey(out, pkey->pkey.dsa, ciph,
NULL, 0, ossl_pem_passwd_cb, passwd)){
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
} else {
if (!PEM_write_bio_DSA_PUBKEY(out, pkey->pkey.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_get_params(VALUE self)
{
EVP_PKEY *pkey;
VALUE hash;
GetPKeyDSA(self, pkey);
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dsa->p));
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.dsa->q));
rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dsa->g));
rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dsa->pub_key));
rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dsa->priv_key));
return hash;
} Сохраняет все параметры ключа в хэш. НЕБЕЗОПАСНО: КОНФИДЕНЦИАЛЬНАЯ ИНФОРМАЦИЯ МОЖЕТ БЫТЬ РАСКРЫТА!!! Не используйте :-)) (Решать вам)
static VALUE
ossl_dsa_is_private(VALUE self)
{
EVP_PKEY *pkey;
GetPKeyDSA(self, pkey);
return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse;
} Указывает, связан ли с этим экземпляром DSA закрытый ключ или нет. Закрытый ключ можно получить с помощью DSA#private_key.
static VALUE
ossl_dsa_is_public(VALUE self)
{
EVP_PKEY *pkey;
GetPKeyDSA(self, pkey);
return (pkey->pkey.dsa->pub_key) ? Qtrue : Qfalse;
} Указывает, связан ли с этим экземпляром 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 */
dsa = DSAPublicKey_dup(pkey->pkey.dsa);
obj = dsa_instance(CLASS_OF(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
static VALUE
ossl_dsa_sign(VALUE self, VALUE data)
{
EVP_PKEY *pkey;
unsigned int buf_len;
VALUE str;
GetPKeyDSA(self, pkey);
if (!pkey->pkey.dsa->q)
ossl_raise(eDSAError, "incomplete DSA");
if (!DSA_PRIVATE(self, pkey->pkey.dsa))
ossl_raise(eDSAError, "Private DSA key needed!");
StringValue(data);
str = rb_str_new(0, ossl_dsa_buf_size(pkey));
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
(unsigned char *)RSTRING_PTR(str),
&buf_len, pkey->pkey.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::SHA1.digest(doc) sig = dsa.syssign(digest)
static VALUE
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
{
EVP_PKEY *pkey;
int ret;
GetPKeyDSA(self, pkey);
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), pkey->pkey.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::SHA1.digest(doc) sig = dsa.syssign(digest) puts dsa.sysverify(digest, sig) # => true
static VALUE
ossl_dsa_to_der(VALUE self)
{
EVP_PKEY *pkey;
int (*i2d_func)_((DSA*, unsigned char**));
unsigned char *p;
long len;
VALUE str;
GetPKeyDSA(self, pkey);
if(DSA_HAS_PRIVATE(pkey->pkey.dsa))
i2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey;
else
i2d_func = i2d_DSA_PUBKEY;
if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0)
ossl_raise(eDSAError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_func(pkey->pkey.dsa, &p) < 0)
ossl_raise(eDSAError, NULL);
ossl_str_adjust(str, p);
return str;
} Кодирует этот объект DSA в его кодировке DER.
static VALUE
ossl_dsa_to_text(VALUE self)
{
EVP_PKEY *pkey;
BIO *out;
VALUE str;
GetPKeyDSA(self, pkey);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (!DSA_print(out, pkey->pkey.dsa, 0)) { /* offset = 0 */
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
str = ossl_membio2str(out);
return str;
} Выводит все параметры ключа в буфер. НЕБЕЗОПАСНО: КОНФИДЕНЦИАЛЬНАЯ ИНФОРМАЦИЯ МОЖЕТ БЫТЬ РАСКРЫТА!!! Не используйте :-)) (Решать вам)
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.