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

OpenSSL::PKey::PKey

父类:Object

捆绑签名创建(PKey#签名)和验证(PKey#验证)的抽象类,除了OpenSSL :: PKey :: DH

  • OpenSSL::PKey::RSA
  • OpenSSL::PKey::DSA
  • OpenSSL::PKey::EC

公共类方法

new → self 显示源

因为PKey是一个抽象类,所以实际调用这个方法会引发一个NotImplementedError

代码语言:javascript
复制
static VALUE
ossl_pkey_initialize(VALUE self)
{
    if (rb_obj_is_instance_of(self, cPKey)) {
        ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly");
    }
    return self;
}

公共实例方法

sign(digest, data) → String 显示源

签署String datadigest,OpenSSL的::文摘的实例,必须提供。返回值又是String包含签名的。如果发生错误,则会引发PKeyError。任何以前的Digest实例状态都与签名结果无关,摘要实例在操作过程中重置为其初始状态。

代码语言:javascript
复制
data = 'Sign me!'
digest = OpenSSL::Digest::SHA256.new
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)
代码语言:javascript
复制
static VALUE
ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
{
    EVP_PKEY *pkey;
    const EVP_MD *md;
    EVP_MD_CTX *ctx;
    unsigned int buf_len;
    VALUE str;
    int result;

    pkey = GetPrivPKeyPtr(self);
    md = GetDigestPtr(digest);
    StringValue(data);
    str = rb_str_new(0, EVP_PKEY_size(pkey));

    ctx = EVP_MD_CTX_new();
    if (!ctx)
        ossl_raise(ePKeyError, "EVP_MD_CTX_new");
    if (!EVP_SignInit_ex(ctx, md, NULL)) {
        EVP_MD_CTX_free(ctx);
        ossl_raise(ePKeyError, "EVP_SignInit_ex");
    }
    if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
        EVP_MD_CTX_free(ctx);
        ossl_raise(ePKeyError, "EVP_SignUpdate");
    }
    result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
    EVP_MD_CTX_free(ctx);
    if (!result)
        ossl_raise(ePKeyError, "EVP_SignFinal");
    rb_str_set_len(str, buf_len);

    return str;
}

verify(digest, signature, data) → String 显示源

为了验证String signaturedigest,OpenSSL的::文摘的实例,必须提供重新计算消息原的消化data,也有String。返回值是true签名有效的情况,false否则。如果发生错误,则会引发PKeyError。任何以前的Digest实例状态都与验证结果无关,摘要实例在操作期间重置为其初始状态。

代码语言:javascript
复制
data = 'Sign me!'
digest = OpenSSL::Digest::SHA256.new
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)
pub_key = pkey.public_key
puts pub_key.verify(digest, signature, data) # => true
代码语言:javascript
复制
static VALUE
ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
{
    EVP_PKEY *pkey;
    const EVP_MD *md;
    EVP_MD_CTX *ctx;
    int siglen, result;

    GetPKey(self, pkey);
    pkey_check_public_key(pkey);
    md = GetDigestPtr(digest);
    StringValue(sig);
    siglen = RSTRING_LENINT(sig);
    StringValue(data);

    ctx = EVP_MD_CTX_new();
    if (!ctx)
        ossl_raise(ePKeyError, "EVP_MD_CTX_new");
    if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
        EVP_MD_CTX_free(ctx);
        ossl_raise(ePKeyError, "EVP_VerifyInit_ex");
    }
    if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
        EVP_MD_CTX_free(ctx);
        ossl_raise(ePKeyError, "EVP_VerifyUpdate");
    }
    result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey);
    EVP_MD_CTX_free(ctx);
    switch (result) {
    case 0:
        ossl_clear_error();
        return Qfalse;
    case 1:
        return Qtrue;
    default:
        ossl_raise(ePKeyError, "EVP_VerifyFinal");
    }
}

扫码关注腾讯云开发者

领取腾讯云代金券