OpenSSL::PKey::RSA
class OpenSSL::PKey::RSA
父类:OpenSSL::PKey::PKey
RSA是一种非对称公钥算法,已在RFC 3447中形式化。它在公共密钥基础设施(PKI)中得到了广泛应用,其中证书(参见OpenSSL :: X509 ::证书)通常基于公共/私人RSA密钥对。RSA用于广泛的应用领域,例如安全(对称)密钥交换,例如建立安全的TLS / SSL连接时。它也用于各种数字签名方案。
公共类方法
generate(size) → RSA instance 显示源
generate(size, exponent) → RSA instance
生成一个RSA密钥对。size
是一个表示所需密钥大小的整数。小于1024的键应被视为不安全。exponent
通常是3,17或65537的奇数。
static VALUE
ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
{
/* why does this method exist? why can't initialize take an optional exponent? */
RSA *rsa;
VALUE size, exp;
VALUE obj;
rb_scan_args(argc, argv, "11", &size, &exp
rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp) /* err handled by rsa_instance */
obj = rsa_instance(klass, rsa
if (obj == Qfalse) {
RSA_free(rsa
ossl_raise(eRSAError, NULL
}
return obj;
}
new(key_size) → RSA instance 显示源
new(encoded_key) → RSA instance
new(encoded_key, pass_phrase) → RSA instance
生成或加载RSA密钥对。如果key_size
给出一个整数,它代表所需的密钥大小。少于1024位的密钥应被视为不安全。
一个密钥可以从一个encoded_key
必须是PEM或DER编码的加载。 pass_phrase
可以用来解密密钥。如果没有提供,OpenSSL将提示输入密码短语。
例子
OpenSSL::PKey::RSA.new 2048
OpenSSL::PKey::RSA.new File.read 'rsa.pem'
OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
static VALUE
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIO *in;
VALUE arg, pass;
GetPKey(self, pkey
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
rsa = RSA_new(
}
else if (RB_INTEGER_TYPE_P(arg)) {
rsa = rsa_generate(NUM2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass)
if (!rsa) ossl_raise(eRSAError, NULL
}
else {
pass = ossl_pem_passwd_value(pass
arg = ossl_to_der_if_possible(arg
in = ossl_obj2bio(arg
rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass
if (!rsa) {
OSSL_BIO_reset(in
rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL
}
if (!rsa) {
OSSL_BIO_reset(in
rsa = d2i_RSAPrivateKey_bio(in, NULL
}
if (!rsa) {
OSSL_BIO_reset(in
rsa = d2i_RSA_PUBKEY_bio(in, NULL
}
if (!rsa) {
OSSL_BIO_reset(in
rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL
}
if (!rsa) {
OSSL_BIO_reset(in
rsa = d2i_RSAPublicKey_bio(in, NULL
}
BIO_free(in
if (!rsa) {
ossl_raise(eRSAError, "Neither PUB key nor PRIV key"
}
}
if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
RSA_free(rsa
ossl_raise(eRSAError, NULL
}
return self;
}
公共实例方法
blinding_off!() Show source
static VALUE
ossl_rsa_blinding_off(VALUE self)
{
RSA *rsa;
GetRSA(self, rsa
RSA_blinding_off(rsa
return self;
}
blinding_on!() Show source
static VALUE
ossl_rsa_blinding_on(VALUE self)
{
RSA *rsa;
GetRSA(self, rsa
if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) {
ossl_raise(eRSAError, NULL
}
return self;
}
export(cipher, pass_phrase) → PEM-format String Show source
to_pem(cipher, pass_phrase) → PEM-format String
to_s(cipher, pass_phrase) → PEM-format String
在PEM编码中输出此密钥对。如果cipher
和pass_phrase
给出,它们将用于加密密钥。cipher
必须是OpenSSL :: Cipher实例。
static VALUE
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
{
RSA *rsa;
BIO *out;
const EVP_CIPHER *ciph = NULL;
VALUE cipher, pass, str;
GetRSA(self, rsa
rb_scan_args(argc, argv, "02", &cipher, &pass
if (!NIL_P(cipher)) {
ciph = GetCipherPtr(cipher
pass = ossl_pem_passwd_value(pass
}
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eRSAError, NULL
}
if (RSA_HAS_PRIVATE(rsa)) {
if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
ossl_pem_passwd_cb, (void *)pass)) {
BIO_free(out
ossl_raise(eRSAError, NULL
}
} else {
if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
BIO_free(out
ossl_raise(eRSAError, NULL
}
}
str = ossl_membio2str(out
return str;
}
另外别名为:to_pem,to_s
params → hash Show source
这种方法是偷偷摸摸,私人信息可能泄露!
将密钥的所有参数存储到散列中。哈希键有'n','e','d','p','q','dmp1','dmq1','iqmp'。
Don't use :-)) (It's up to you)
static VALUE
ossl_rsa_get_params(VALUE self)
{
RSA *rsa;
VALUE hash;
const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
GetRSA(self, rsa
RSA_get0_key(rsa, &n, &e, &d
RSA_get0_factors(rsa, &p, &q
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp
hash = rb_hash_new(
rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n)
rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e)
rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d)
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("dmp1"), ossl_bn_new(dmp1)
rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1)
rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp)
return hash;
}
private? → true | false Show source
这个密钥对是否包含私钥?
static VALUE
ossl_rsa_is_private(VALUE self)
{
RSA *rsa;
GetRSA(self, rsa
return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse;
}
private_decrypt(string) → String Show source
private_decrypt(string, padding) → String
string
用公钥加密的解密,用私钥解密。padding
默认为PKCS1_PADDING。
static VALUE
ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
{
RSA *rsa;
const BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetRSA(self, rsa
RSA_get0_key(rsa, &rsa_n, NULL, NULL
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA"
if (!RSA_PRIVATE(self, rsa))
ossl_raise(eRSAError, "private key needed."
rb_scan_args(argc, argv, "11", &buffer, &padding
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding
StringValue(buffer
str = rb_str_new(0, RSA_size(rsa)
buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad
if (buf_len < 0) ossl_raise(eRSAError, NULL
rb_str_set_len(str, buf_len
return str;
}
private_encrypt(string) → String Show source
private_encrypt(string, padding) → String
加密string
用私钥。padding
默认为PKCS1_PADDING。加密的字符串输出可以使用public_decrypt解密。
static VALUE
ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
{
RSA *rsa;
const BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetRSA(self, rsa
RSA_get0_key(rsa, &rsa_n, NULL, NULL
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA"
if (!RSA_PRIVATE(self, rsa))
ossl_raise(eRSAError, "private key needed."
rb_scan_args(argc, argv, "11", &buffer, &padding
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding
StringValue(buffer
str = rb_str_new(0, RSA_size(rsa)
buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad
if (buf_len < 0) ossl_raise(eRSAError, NULL
rb_str_set_len(str, buf_len
return str;
}
public? → true Show source
返回值总是为真,因为每个私钥也是一个公钥。
static VALUE
ossl_rsa_is_public(VALUE self)
{
RSA *rsa;
GetRSA(self, rsa
/*
* This method should check for n and e. BUG.
*/
(void)rsa;
return Qtrue;
}
public_decrypt(string) → String Show source
public_decrypt(string, padding) → String
string
用公钥加密的用私钥加密的解密。padding
默认为PKCS1_PADDING。
static VALUE
ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
{
RSA *rsa;
const BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetRSA(self, rsa
RSA_get0_key(rsa, &rsa_n, NULL, NULL
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA"
rb_scan_args(argc, argv, "11", &buffer, &padding
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding
StringValue(buffer
str = rb_str_new(0, RSA_size(rsa)
buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad
if (buf_len < 0) ossl_raise(eRSAError, NULL
rb_str_set_len(str, buf_len
return str;
}
public_encrypt(string) → String Show source
public_encrypt(string, padding) → String
string
用公钥加密。padding
默认为PKCS1_PADDING。加密的字符串输出可以使用private_decrypt解密。
static VALUE
ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
{
RSA *rsa;
const BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetRSA(self, rsa
RSA_get0_key(rsa, &rsa_n, NULL, NULL
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA"
rb_scan_args(argc, argv, "11", &buffer, &padding
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding
StringValue(buffer
str = rb_str_new(0, RSA_size(rsa)
buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad
if (buf_len < 0) ossl_raise(eRSAError, NULL
rb_str_set_len(str, buf_len
return str;
}
public_key → RSA Show source
使用私钥包含公钥的新RSA实例。
static VALUE
ossl_rsa_to_public_key(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
VALUE obj;
GetPKeyRSA(self, pkey
/* err check performed by rsa_instance */
rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey)
obj = rsa_instance(rb_obj_class(self), rsa
if (obj == Qfalse) {
RSA_free(rsa
ossl_raise(eRSAError, NULL
}
return obj;
}
set_crt_params(dmp1, dmq1, iqmp) → self
套dmp1
,dmq1
,iqmp
为RSA实例。它们被计算d mod (p - 1)
,d mod (q - 1)
并q^(-1) mod p
分别。
set_factors(p, q) → self
设置p
,q
为RSA实例。
set_key(n, e, d) → self
套n
,e
,d
为RSA实例。
to_der→DER格式字符串显示源
在DER编码中输出此密钥对。
static VALUE
ossl_rsa_to_der(VALUE self)
{
RSA *rsa;
int (*i2d_func)(const RSA *, unsigned char **
unsigned char *p;
long len;
VALUE str;
GetRSA(self, rsa
if (RSA_HAS_PRIVATE(rsa))
i2d_func = i2d_RSAPrivateKey;
else
i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY;
if((len = i2d_func(rsa, NULL)) <= 0)
ossl_raise(eRSAError, NULL
str = rb_str_new(0, len
p = (unsigned char *)RSTRING_PTR(str
if(i2d_func(rsa, &p) < 0)
ossl_raise(eRSAError, NULL
ossl_str_adjust(str, p
return str;
}
to_pem(p1 = v1, p2 = v2)
别名为:导出
to_s(p1 = v1, p2 = v2)
别名为:导出
to_text → String 显示源
这种方法是偷偷摸摸,私人信息可能泄露!
将密钥对的所有参数转储到String
不要使用:-))(这取决于你)
static VALUE
ossl_rsa_to_text(VALUE self)
{
RSA *rsa;
BIO *out;
VALUE str;
GetRSA(self, rsa
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eRSAError, NULL
}
if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
BIO_free(out
ossl_raise(eRSAError, NULL
}
str = ossl_membio2str(out
return str;
}