正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要 。
RSA算法是一个广泛使用的公钥算法。其密钥包括公钥和私钥。它能用于数字签名、身份认证以及密钥交换。RSA密钥长度一般使用1024位或者更高。RSA密钥信息主要包括:
n:模数
e:公钥指数
d:私钥指数
p:最初的大素数
q:最初的大素数
其中,公钥为n和e;私钥为n和d。
本文假设你已经安装好了OpenSSL,并且持有一份1.1.1的源码。
RSA相关的头文件在rsa.h中、源文件在crypto/rsa目录中。
这个结构定义了RSA内部数据信息。主要字段含义:
version —— 版本。
meth —— RSA运算抽象方法集合。
n,e,d,p,q,dmp1,dmq1,iqmp —— 密钥相关的大数。
这个结构定义了RSA内部各种运算抽象方法集合。主要字段含义:
name —— 名称描述。
rsa_pub_enc —— 公钥加密方法。
rsa_pub_dec —— 公钥解密方法。
rsa_priv_enc —— 私钥加密方法。
rsa_priv_dec —— 公钥解密方法。
rsa_sign —— 签名方法。
rsa_verify —— 验签方法。
rsa_keygen —— 生成密钥对方法。
在1.1.1中,大多数的数据结构已经不再向使用者开放,从封装的角度来看,这是更合理的。如果你在头文件中找不到结构定义,不妨去源码中搜一搜。
RSA *RSA_new(void)
生成一个RSA密钥结构,采用默认的rsa_pkcs1_ossl_meth方法。
void RSA_free(RSA *r)
释放RSA结构。
RSA *RSA_generate_key(int bits, unsigned long e, void (*callback) (int, int, void *), void *cb_arg)
生成RSA密钥(旧版本)。
bits为密钥位数,e为公钥指数。
callback为密钥生成过程中的干预回调函数,通常传入NULL。cb_arg为回调参数。
成功返回RSA指针,失败返回NULL。
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
生成RSA密钥(新版本)。
rsa为RSA对象指针。bits为密钥位置,e为公钥指数的大数形式指针。cb为干预回调函数,通常传入NULL。
成功返回1,失败返回0。
关于公钥指数e,主要有两个取值:
# define RSA_3 0x3L
# define RSA_F4 0x10001L
RSA *RSAPublicKey_dup(RSA *rsa)
复制RSA公钥部分。
成功返回RSA指针,失败返回NULL。
RSA *RSAPrivateKey_dup(RSA *rsa)
复制RSA私钥部分。
成功返回RSA指针,失败返回NULL。
int RSA_bits(const RSA *rsa)
获取RSA密钥位数。
int RSA_size(const RSA *rsa)
获取RSA密钥长度。
int RSA_check_key(const RSA *)
int RSA_check_key_ex(const RSA *, BN_GENCB *cb)
检查RSA的有效性,必须为完整的密钥对。
成功返回1,失败返回0。
int RSA_print(BIO *bp, const RSA *r, int offset)
int RSA_print_fp(FILE *fp, const RSA *r, int offset)
将RSA信息输出到bp/fp中,off为输出信息在bp/fp中的偏移量,比如是屏幕bp/fp,则表示打印信息的位置离左边屏幕边缘的距离。
int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
RSA公钥加密。
成功返回密文的长度,失败返回-1。
int RSA_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
RSA公钥解密。
成功返回明文的长度,失败返回-1。
int RSA_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
RSA私钥加密。
成功返回密文的长度,失败返回-1。
int RSA_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
RSA私钥解密。
成功返回明文的长度,失败返回-1。
关于padding填充方式,取值:
其中PKCS1填充大小为11字节,所以加密明文长度必须不大于(密钥大小-11字节)。
# define RSA_PKCS1_PADDING_SIZE 11
int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen, RSA *rsa)
对数据m生成RSA签名,生成的签名长度与key的长度相同,如512位密钥生成64字节签名。
type指定摘要算法的NID,如NID_sha1。
成功返回1,失败返回0。
int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
对数据m验证RSA签名。
type指定摘要算法的NID,如NID_sha1。
成功返回1,失败返回0。
以下函数在x509.h中定义:
int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa)
}
将RSA公钥转换为DER编码,并写入到bp抽象IO中。
成功返回1,失败返回0。
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa)
}
从bp抽象IO中读取DER编码,并转换为rsa结构私钥。
成功返回有效指定,失败返回NULL。
int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa)
}
将RSA公钥转换为DER编码,并写入到bp抽象IO中。
成功返回1,失败返回0。
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa)
}
从bp抽象IO中读取DER编码,并转换为rsa结构公钥。
成功返回有效指定,失败返回NULL。
下面这个例子演示了RSA密钥对的生成、公私钥的复制、公钥加密和私钥解密的用法。
输出:
下面这个例子演示了公私钥的分开保存、读取,以及使用公私钥加解密。
输出:
RSA_generate_key_ex() ret:1
i2d_RSAPrivateKey_bio() ret:1
i2d_RSAPublicKey_bio() ret:1
copy' private key size:64
copy' public key size:64
RSA_public_encrypt() ret:64
RSA_private_decrypt() ret:10
text:[1234567890]
下面这个例子演示了签名的生成和验证 *** 作。
输出:
ret:1
RSA_sign() ret:1
sign 64
4ec0af099c49646b72fda88a4fb11e8deb3898da9c3f611a5f25f05d9d005631858239bbb732cd5060dbc975363fc1b9cdfdc5a04554115a916f06f98163189f
RSA_verify() ret:1
openssl 生成并输入一个RSA私钥 输出参数 私钥名称 对应的nopenssl genrsa-out private.pem 1024
openssl 处理RSA密钥的格式转换等问题提取 输出参数 公钥名称
openssl rsa -in private.pem -pubout -out public.pem
openssl 使用RSA密钥进行加密、解密、签名和验证等运算加密参数 输入 明文内容 放入密钥参数 公钥文件 输入 输出 文件名
openssl rsautl -encrypt -in message.txt -inkey public.pem -pubin -out enc.txt
openssl 使用RSA密钥进行加密、解密、签名和验证等运算 解密参数 输入 加密文件放入密钥参数 私钥文件 输出 输出文件名
opensslrsautl -decrypt-in enc.txt -inkey private.pem -out dec.txt
openssl 使用RSA密钥进行加密、解密、签名和验证等运算 签名 输入 明文文件放入密钥参数私钥文件 输出文件名
openssl rsautl-sign -in message.txt -inkey private.pem -out enc.bin
openssl 使用RSA密钥进行加密、解密、签名和验证等运算 验证 输入 加密文件 放入密钥参数 公钥文件 输入参数 输出 明文文件
openssl rsautl-verify-in enc.bin -inkey public.pem -pubin -outdec.txt
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)