module OpenSSL::PKey
非对称公钥算法
非对称公钥算法解决了用于加密/解密消息的秘密密钥的建立和共享问题。这种算法中的密钥由两部分组成:一部分是公钥,可以分发给他人;另一部分是私钥,需要保密。
用公钥加密的消息只能由拥有相应私钥的接收者解密。由于非对称公钥算法比对称密钥算法(参见 OpenSSL::Cipher)慢得多,因此它们经常被用来建立在双方都拥有对方公钥的情况下共享的对称密钥。
非对称算法提供了许多不错的特性,这些特性在许多不同的领域都有应用。一个非常常见的应用是创建和验证数字签名。要签署文档,签名者通常使用消息摘要算法(参见 OpenSSL::Digest)来计算文档的摘要,然后使用私钥对其进行加密(即签名)。任何拥有公钥的人都可以通过自己计算原始文档的消息摘要,使用签名者的公钥解密签名,并将其结果与之前计算的消息摘要进行比较来验证签名。签名仅在解密后的签名等于该消息摘要时才有效。
PKey 模块支持三种流行的公钥/私钥算法:
-
椭圆曲线密码学 (
OpenSSL::PKey::EC)
实际上,这些实现中的每一个都是抽象的 PKey 类的子类,它提供了以 PKey#sign 和 PKey#verify 形式支持数字签名的接口。
Diffie-Hellman 密钥交换
最后,PKey 还提供了 OpenSSL::PKey::DH,这是基于有限域离散对数的 Diffie-Hellman 密钥交换协议的实现,这与 DSA 的基础相同。DH 协议可用于在不安全的通道上交换(对称)密钥,而无需参与方之间有任何先前的联合知识。由于 DH 的安全性要求相对较长的“公钥”(即在参与者之间公开传输的部分),因此 DH 通常速度较慢。如果安全或速度是您的主要考虑因素,OpenSSL::PKey::EC 提供了 Diffie-Hellman 协议的另一种实现。
Constants
Public Class Methods
Source
static VALUE
ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self)
{
return pkey_generate(argc, argv, self, 0);
}
生成一个新的密钥(对)。
如果第一个参数是 String,它会像 ::generate_parameters 一样,为指定的算法生成一个新的随机密钥。如果给定的不是 OpenSSL::PKey::PKey,它将为与密钥相同的算法生成一个新的随机密钥,使用该密钥包含的参数。
有关 *options* 和给定块的详细信息,请参阅 ::generate_parameters。
示例
pkey_params = OpenSSL::PKey.generate_parameters("DSA", "dsa_paramgen_bits" => 2048) pkey_params.priv_key #=> nil pkey = OpenSSL::PKey.generate_key(pkey_params) pkey.priv_key #=> #<OpenSSL::BN 6277...
Source
static VALUE
ossl_pkey_s_generate_parameters(int argc, VALUE *argv, VALUE self)
{
return pkey_generate(argc, argv, self, 1);
}
Source
static VALUE
ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)
{
EVP_PKEY *pkey;
size_t keylen;
StringValue(key);
keylen = RSTRING_LEN(key);
#ifdef OSSL_USE_PROVIDER
pkey = EVP_PKEY_new_raw_private_key_ex(NULL, StringValueCStr(type), NULL,
(unsigned char *)RSTRING_PTR(key),
keylen);
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key_ex");
#else
int pkey_id = lookup_pkey_type(type);
pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key");
#endif
return ossl_pkey_wrap(pkey);
}
请参阅 OpenSSL 文档中的 EVP_PKEY_new_raw_private_key()。
Source
static VALUE
ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)
{
EVP_PKEY *pkey;
size_t keylen;
StringValue(key);
keylen = RSTRING_LEN(key);
#ifdef OSSL_USE_PROVIDER
pkey = EVP_PKEY_new_raw_public_key_ex(NULL, StringValueCStr(type), NULL,
(unsigned char *)RSTRING_PTR(key),
keylen);
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key_ex");
#else
int pkey_id = lookup_pkey_type(type);
pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
if (!pkey)
ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key");
#endif
return ossl_pkey_wrap(pkey);
}
请参阅 OpenSSL 文档中的 EVP_PKEY_new_raw_public_key()。
Source
static VALUE
ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
BIO *bio;
VALUE data, pass;
rb_scan_args(argc, argv, "11", &data, &pass);
bio = ossl_obj2bio(&data);
pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass));
BIO_free(bio);
if (!pkey)
ossl_raise(ePKeyError, "Could not parse PKey");
return ossl_pkey_wrap(pkey);
}