首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

OpenSSL::PKey::DH

父类:OpenSSL::PKey::PKey

基于有限域内离散对数的Diffie-Hellman密钥交换协议的实现,与构建DSA的基础相同。

Diffie-Hellman参数的访问器方法

Kernel#p

Diffie-Hellman参数的素数(OpenSSL :: BN)。

DH#g

生成器(OpenSSL :: BN)的Diffie-Hellman参数。

DH#pub_key

每个会话公钥(一个OpenSSL :: BN)与私钥匹配。这需要传递给#compute_key。

DH#priv_key

每个会话私钥,一个OpenSSL :: BN。

密钥交换的例子

代码语言:javascript
复制
dh1 = OpenSSL::PKey::DH.new(2048)
der = dh1.public_key.to_der #you may send this publicly to the participating party
dh2 = OpenSSL::PKey::DH.new(der)
dh2.generate_key! #generate the per-session key pair
symm_key1 = dh1.compute_key(dh2.pub_key)
symm_key2 = dh2.compute_key(dh1.pub_key)

puts symm_key1 == symm_key2 # => true

公共类方法

生成(大小,生成器)→dh显示源

通过生成私有和公共组件,从头开始创建一个新的DH实例。

参数

  • size是一个表示所需密钥大小的整数。小于1024位的密钥应被视为不安全。
  • generator 是少数> 1,通常是2或5。
代码语言:javascript
复制
static VALUE
ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
{
    DH *dh ;
    int g = 2;
    VALUE size, gen, obj;

    if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
        g = NUM2INT(gen);
    }
    dh = dh_generate(NUM2INT(size), g);
    obj = dh_instance(klass, dh);
    if (obj == Qfalse) {
        DH_free(dh);
        ossl_raise(eDHError, NULL);
    }

    return obj;
}

new→dh显示源

new(string) → dh

new(size , generator) → dh

要么从头开始生成DH实例,要么通过读取已有的DH参数string。请注意,当使用#to_pem或#to_der从DH实例编码的数据中读取DH实例时,结果将包含公钥/私钥对。这需要使用#generate_key生成!第一。

参数

  • size是一个表示所需密钥大小的整数。小于1024位的密钥应被视为不安全。
  • generator 是少数> 1,通常是2或5。
  • string包含DER或PEM编码密钥。示例DH.new# - > DH DH.new(1024)# - > DH DH.new(1024,5)# - > DH#读DH参数DH = DH.new(File.read ('parameters.pem'))# - > dh,但没有公钥/私钥但dh.generate_key!# - > dh与公共和私人keystatic VALUE ossl_dh_initialize(int argc,VALUE * argv,VALUE self){EVP_PKEY * pkey; DH * dh; int g = 2; BIO * in; VALUE arg,gen; GetPKey(self,pkey); if(rb_scan_args(argc,argv,“02”,&arg,&gen)== 0){dh = DH_new(); } else if(RB_INTEGER_TYPE_P(arg)){if(!NIL_P(gen)){g = NUM??2INT(gen); } if(!(dh = dh_generate(NUM2INT(arg),g))){ossl_raise(eDHError,NULL); }} else {arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); dh = PEM_read_bio_DHparams(in,NULL,NULL,NULL); if(!dh){OSSL_BIO_reset(in); dh = d2i_DHparams_bio(in,NULL); } BIO_free(in); if(!dh){ossl_raise(eDHError,NULL); (!EVP_PKEY_assign_DH(pkey,dh)){DH_free(dh);} ossl_raise(eDHError,NULL); }返回自我; }公共实例方法compute_key(pub_bn)→aString显示源返回一个字符串,其中包含从对方的公共值计算出来的共享密钥。请参阅DH_compute_key()以获取更多信息。参数 dh){ossl_raise(eDHError,NULL); (!EVP_PKEY_assign_DH(pkey,dh)){DH_free(dh);} ossl_raise(eDHError,NULL); }返回自我; }公共实例方法compute_key(pub_bn)→aString显示源返回一个字符串,其中包含从对方的公共值计算出来的共享密钥。请参阅DH_compute_key()以获取更多信息。参数 dh){ossl_raise(eDHError,NULL); (!EVP_PKEY_assign_DH(pkey,dh)){DH_free(dh);} ossl_raise(eDHError,NULL); }返回自我; }公共实例方法compute_key(pub_bn)→aString显示源返回一个字符串,其中包含从对方的公共值计算出来的共享密钥。请参阅DH_compute_key()以获取更多信息。参数
  • pub_bn是OpenSSL :: BN,而不是由#public_key返回的DH实例,因为它只包含DH参数。
代码语言:javascript
复制
static VALUE
ossl_dh_compute_key(VALUE self, VALUE pub)
{
    DH *dh;
    const BIGNUM *pub_key, *dh_p;
    VALUE str;
    int len;

    GetDH(self, dh);
    DH_get0_pqg(dh, &dh_p, NULL, NULL);
    if (!dh_p)
        ossl_raise(eDHError, "incomplete DH");
    pub_key = GetBNPtr(pub);
    len = DH_size(dh);
    str = rb_str_new(0, len);
    if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
        ossl_raise(eDHError, NULL);
    }
    rb_str_set_len(str, len);

    return str;
}

导出→aString显示源

to_pem → aString

to_s → aString

将此DH编码为其PEM编码。请注意,任何现有的每会话公钥/私钥都不会被编码,只有Diffie-Hellman参数将被编码。

代码语言:javascript
复制
static VALUE
ossl_dh_export(VALUE self)
{
    DH *dh;
    BIO *out;
    VALUE str;

    GetDH(self, dh);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eDHError, NULL);
    }
    if (!PEM_write_bio_DHparams(out, dh)) {
        BIO_free(out);
        ossl_raise(eDHError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}

另外别名为:to_pem,to_s

generate_key! → self Show source

生成私钥和公钥,除非私钥已经存在。如果此DH实例是从公共DH参数生成的(例如,通过编码#public_key的结果),则需要首先调用此方法以便在执行实际密钥交换之前生成每个会话密钥。

代码语言:javascript
复制
dh = OpenSSL::PKey::DH.new(2048)
public_key = dh.public_key #contains no private/public key yet
public_key.generate_key!
puts public_key.private? # => true
代码语言:javascript
复制
static VALUE
ossl_dh_generate_key(VALUE self)
{
    DH *dh;

    GetDH(self, dh);
    if (!DH_generate_key(dh))
        ossl_raise(eDHError, "Failed to generate key");
    return self;
}

params→哈希显示源码

将密钥的所有参数存储到散列INSECURE:PRIVATE INFORMATIONS CAN LEAK OUT !!! 不要使用:-))(我由你决定)

代码语言:javascript
复制
static VALUE
ossl_dh_get_params(VALUE self)
{
    DH *dh;
    VALUE hash;
    const BIGNUM *p, *q, *g, *pub_key, *priv_key;

    GetDH(self, dh);
    DH_get0_pqg(dh, &p, &q, &g);
    DH_get0_key(dh, &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;
}

params_ok?→true | false 显示源

验证与此实例关联的Diffie-Hellman参数。它会检查是否使用了安全的素数和合适的发生器。如果不是这样,false则返回。

代码语言:javascript
复制
static VALUE
ossl_dh_check_params(VALUE self)
{
    DH *dh;
    int codes;

    GetDH(self, dh);
    if (!DH_check(dh, &codes)) {
        return Qfalse;
    }

    return codes == 0 ? Qtrue : Qfalse;
}

private? → true | false 显示源

指示此DH实例是否具有与其关联的私钥。私钥可以用DH#priv_key检索。

代码语言:javascript
复制
static VALUE
ossl_dh_is_private(VALUE self)
{
    DH *dh;
    const BIGNUM *bn;

    GetDH(self, dh);
    DH_get0_key(dh, NULL, &bn);

#if !defined(OPENSSL_NO_ENGINE)
    return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse;
#else
    return bn ? Qtrue : Qfalse;
#endif
}

public? → true | false 显示源

指示此DH实例是否具有与其关联的公钥。公钥可以用DH#pub_key检索。

代码语言:javascript
复制
static VALUE
ossl_dh_is_public(VALUE self)
{
    DH *dh;
    const BIGNUM *bn;

    GetDH(self, dh);
    DH_get0_key(dh, &bn, NULL);

    return bn ? Qtrue : Qfalse;
}

public_key → aDH 显示源

返回仅携带公共信息的新DH实例,即主要部分p和生成器g,但尚无公钥/私钥。这样的一对可以使用#generate_key!生成。与#compute_key进行密钥交换所需的“公钥”被视为每会话信息,并且一旦生成密钥对,可以使用DH#pub_key检索该公钥。如果当前实例已经包含私人信息(并且因此包含有效的公钥/私钥对),则此信息将不再存在于由#public_key生成的新实例中。此功能有助于发布Diffie-Hellman参数而不泄漏任何专用的每会话信息。

代码语言:javascript
复制
dh = OpenSSL::PKey::DH.new(2048) # has public and private key set
public_key = dh.public_key # contains only prime and generator
parameters = public_key.to_der # it's safe to publish this
代码语言:javascript
复制
static VALUE
ossl_dh_to_public_key(VALUE self)
{
    DH *orig_dh, *dh;
    VALUE obj;

    GetDH(self, orig_dh);
    dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */
    obj = dh_instance(rb_obj_class(self), dh);
    if (obj == Qfalse) {
        DH_free(dh);
        ossl_raise(eDHError, NULL);
    }

    return obj;
}

set_key(pub_key, priv_key) → self

设置pub_keypriv_keyDH实例。priv_key可能是零。

set_pqg(p, q, g) → self

pqg为DH实例。

to_der → aString 显示源

将此DH编码为其DER编码。请注意,任何现有的每会话公钥/私钥都不会被编码,只有Diffie-Hellman参数将被编码。

代码语言:javascript
复制
static VALUE
ossl_dh_to_der(VALUE self)
{
    DH *dh;
    unsigned char *p;
    long len;
    VALUE str;

    GetDH(self, dh);
    if((len = i2d_DHparams(dh, NULL)) <= 0)
        ossl_raise(eDHError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_DHparams(dh, &p) < 0)
        ossl_raise(eDHError, NULL);
    ossl_str_adjust(str, p);

    return str;
}

to_pem()

别名为:导出

to_s()

别名为:导出

to_text → aString 显示源

打印缓冲区的所有参数键INSECURE:私人信息可以泄漏!不要使用:-))(我由你决定)

代码语言:javascript
复制
static VALUE
ossl_dh_to_text(VALUE self)
{
    DH *dh;
    BIO *out;
    VALUE str;

    GetDH(self, dh);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eDHError, NULL);
    }
    if (!DHparams_print(out, dh)) {
        BIO_free(out);
        ossl_raise(eDHError, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com