类 OpenSSL::Netscape::SPKI
简单公钥基础设施实现(发音为“spooky”)。该结构定义为
PublicKeyAndChallenge ::= SEQUENCE { spki SubjectPublicKeyInfo, challenge IA5STRING } SignedPublicKeyAndChallenge ::= SEQUENCE { publicKeyAndChallenge PublicKeyAndChallenge, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING }
其中 SubjectPublicKeyInfo 和 AlgorithmIdentifier 的定义可以在 RFC5280 中找到。 SPKI
通常用于浏览器中,使用 HTML <keygen> 元素生成公钥/私钥对和后续证书请求。
示例¶ ↑
创建 SPKI
¶ ↑
key = OpenSSL::PKey::RSA.new 2048 spki = OpenSSL::Netscape::SPKI.new spki.challenge = "RandomChallenge" spki.public_key = key.public_key spki.sign(key, OpenSSL::Digest.new('SHA256')) #send a request containing this to a server generating a certificate
验证 SPKI
请求¶ ↑
request = #... spki = OpenSSL::Netscape::SPKI.new request unless spki.verify(spki.public_key) # signature is invalid end #proceed
公共类方法
new([request]) → spki 点击切换源代码
参数¶ ↑
-
request - 可选的原始请求,以 PEM 或 DER 格式。
static VALUE ossl_spki_initialize(int argc, VALUE *argv, VALUE self) { NETSCAPE_SPKI *spki; VALUE buffer; const unsigned char *p; if (rb_scan_args(argc, argv, "01", &buffer) == 0) { return self; } StringValue(buffer); if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), RSTRING_LENINT(buffer)))) { ossl_clear_error(); p = (unsigned char *)RSTRING_PTR(buffer); if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) { ossl_raise(eSPKIError, NULL); } } NETSCAPE_SPKI_free(DATA_PTR(self)); SetSPKI(self, spki); return self; }
公共实例方法
challenge → string 点击切换源代码
返回与该 SPKI
关联的挑战字符串。
static VALUE ossl_spki_get_challenge(VALUE self) { NETSCAPE_SPKI *spki; GetSPKI(self, spki); if (spki->spkac->challenge->length <= 0) { OSSL_Debug("Challenge.length <= 0?"); return rb_str_new(0, 0); } return rb_str_new((const char *)spki->spkac->challenge->data, spki->spkac->challenge->length); }
challenge = str → string 点击切换源代码
参数¶ ↑
-
str - 要为该实例设置的挑战字符串
设置与 SPKI
关联的挑战。可由服务器使用,例如,防止重放。
static VALUE ossl_spki_set_challenge(VALUE self, VALUE str) { NETSCAPE_SPKI *spki; StringValue(str); GetSPKI(self, spki); if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str), RSTRING_LENINT(str))) { ossl_raise(eSPKIError, NULL); } return str; }
public_key → pkey 点击切换源代码
返回与 SPKI
关联的公钥,一个 OpenSSL::PKey
实例。
static VALUE ossl_spki_get_public_key(VALUE self) { NETSCAPE_SPKI *spki; EVP_PKEY *pkey; GetSPKI(self, spki); if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */ ossl_raise(eSPKIError, NULL); } return ossl_pkey_new(pkey); /* NO DUP - OK */ }
public_key = pub → pkey 点击切换源代码
参数¶ ↑
-
pub - 要为该实例设置的公钥
设置与 SPKI
关联的公钥,一个 OpenSSL::PKey
实例。这应该是与用于签署 SPKI
的私钥相对应的公钥。
static VALUE ossl_spki_set_public_key(VALUE self, VALUE key) { NETSCAPE_SPKI *spki; EVP_PKEY *pkey; GetSPKI(self, spki); pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey"); return key; }
sign(key, digest) → spki 点击切换源代码
参数¶ ↑
-
key - 用于签署该实例的私钥
-
digest - 用于签署该实例的摘要
要签署 SPKI
,应使用与为该实例设置的公钥相对应的私钥,以及一个 OpenSSL::Digest
形式的摘要算法。私钥应该是 OpenSSL::PKey
的实例。
static VALUE ossl_spki_sign(VALUE self, VALUE key, VALUE digest) { NETSCAPE_SPKI *spki; EVP_PKEY *pkey; const EVP_MD *md; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ md = ossl_evp_get_digestbyname(digest); GetSPKI(self, spki); if (!NETSCAPE_SPKI_sign(spki, pkey, md)) { ossl_raise(eSPKIError, NULL); } return self; }
to_der → DER 编码的字符串 点击切换源代码
返回该 SPKI
的 DER 编码。
static VALUE ossl_spki_to_der(VALUE self) { NETSCAPE_SPKI *spki; VALUE str; long len; unsigned char *p; GetSPKI(self, spki); if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0) ossl_raise(eX509CertError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_NETSCAPE_SPKI(spki, &p) <= 0) ossl_raise(eX509CertError, NULL); ossl_str_adjust(str, p); return str; }
to_pem → PEM 编码的字符串 点击切换源代码
返回该 SPKI
的 PEM 编码。
static VALUE ossl_spki_to_pem(VALUE self) { NETSCAPE_SPKI *spki; char *data; VALUE str; GetSPKI(self, spki); if (!(data = NETSCAPE_SPKI_b64_encode(spki))) { ossl_raise(eSPKIError, NULL); } str = ossl_buf2str(data, rb_long2int(strlen(data))); return str; }
也称为: to_s
to_s
别名: to_pem
to_text → string 点击切换源代码
返回该 SPKI
的文本表示,有助于调试。
static VALUE ossl_spki_print(VALUE self) { NETSCAPE_SPKI *spki; BIO *out; GetSPKI(self, spki); if (!(out = BIO_new(BIO_s_mem()))) { ossl_raise(eSPKIError, NULL); } if (!NETSCAPE_SPKI_print(out, spki)) { BIO_free(out); ossl_raise(eSPKIError, NULL); } return ossl_membio2str(out); }
verify(key) → boolean 点击切换源代码
参数¶ ↑
-
key - 用于验证
SPKI
签名的公钥
如果签名有效,则返回 true
,否则返回 false
。要验证 SPKI
,应使用 SPKI
中包含的公钥。
static VALUE ossl_spki_verify(VALUE self, VALUE key) { NETSCAPE_SPKI *spki; EVP_PKEY *pkey; GetSPKI(self, spki); pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); switch (NETSCAPE_SPKI_verify(spki, pkey)) { case 0: ossl_clear_error(); return Qfalse; case 1: return Qtrue; default: ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify"); } }