赞
踩
RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制 。在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK 。
正是基于这种理论,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目录中。
- struct rsa_st {
- /*
- * The first parameter is used to pickup errors where this is passed
- * instead of an EVP_PKEY, it is set to 0
- */
- int pad;
- int32_t version;
- const RSA_METHOD *meth;
- /* functional reference if 'meth' is ENGINE-provided */
- ENGINE *engine;
- BIGNUM *n;
- BIGNUM *e;
- BIGNUM *d;
- BIGNUM *p;
- BIGNUM *q;
- BIGNUM *dmp1;
- BIGNUM *dmq1;
- BIGNUM *iqmp;
- /* for multi-prime RSA, defined in RFC 8017 */
- STACK_OF(RSA_PRIME_INFO) *prime_infos;
- /* If a PSS only key this contains the parameter restrictions */
- RSA_PSS_PARAMS *pss;
- /* be careful using this if the RSA structure is shared */
- CRYPTO_EX_DATA ex_data;
- CRYPTO_REF_COUNT references;
- int flags;
- /* Used to cache montgomery values */
- BN_MONT_CTX *_method_mod_n;
- BN_MONT_CTX *_method_mod_p;
- BN_MONT_CTX *_method_mod_q;
- /*
- * all BIGNUM values are actually in the following data, if it is not
- * NULL
- */
- char *bignum_data;
- BN_BLINDING *blinding;
- BN_BLINDING *mt_blinding;
- CRYPTO_RWLOCK *lock;
- };
- typedef struct rsa_st RSA;
这个结构定义了RSA内部数据信息。主要字段含义:
version —— 版本。
meth —— RSA运算抽象方法集合。
n,e,d,p,q,dmp1,dmq1,iqmp —— 密钥相关的大数。
- struct rsa_meth_st {
- char *name;
- int (*rsa_pub_enc) (int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding);
- int (*rsa_pub_dec) (int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding);
- int (*rsa_priv_enc) (int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding);
- int (*rsa_priv_dec) (int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding);
- /* Can be null */
- int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
- /* Can be null */
- int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
- /* called at new */
- int (*init) (RSA *rsa);
- /* called at free */
- int (*finish) (RSA *rsa);
- /* RSA_METHOD_FLAG_* things */
- int flags;
- /* may be needed! */
- char *app_data;
- /*
- * New sign and verify functions: some libraries don't allow arbitrary
- * data to be signed/verified: this allows them to be used. Note: for
- * this to work the RSA_public_decrypt() and RSA_private_encrypt() should
- * *NOT* be used RSA_sign(), RSA_verify() should be used instead.
- */
- int (*rsa_sign) (int type,
- const unsigned char *m, unsigned int m_length,
- unsigned char *sigret, unsigned int *siglen,
- const RSA *rsa);
- int (*rsa_verify) (int dtype, const unsigned char *m,
- unsigned int m_length, const unsigned char *sigbuf,
- unsigned int siglen, const RSA *rsa);
- /*
- * If this callback is NULL, the builtin software RSA key-gen will be
- * used. This is for behavioural compatibility whilst the code gets
- * rewired, but one day it would be nice to assume there are no such
- * things as "builtin software" implementations.
- */
- int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
- int (*rsa_multi_prime_keygen) (RSA *rsa, int bits, int primes,
- BIGNUM *e, BN_GENCB *cb);
- };
- typedef struct rsa_meth_st RSA_METHOD;
这个结构定义了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填充方式,取值:
- # define RSA_PKCS1_PADDING 1
- # define RSA_SSLV23_PADDING 2
- # define RSA_NO_PADDING 3
- # define RSA_PKCS1_OAEP_PADDING 4
- # define RSA_X931_PADDING 5
- /* EVP_PKEY_ only */
- # define RSA_PKCS1_PSS_PADDING 6
其中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密钥对的生成、公私钥的复制、公钥加密和私钥解密的用法。
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
-
- #include <openssl/rsa.h>
- #include <openssl/err.h>
-
- namespace dakuang {}
-
- int main(int argc, char* argv[])
- {
- ERR_load_RSA_strings();
-
- RSA* pRSA = RSA_generate_key(512, RSA_3, NULL, NULL);
- RSA_print_fp(stdout, pRSA , 0);
- RSA_free(pRSA);
-
- pRSA = RSA_new();
- BIGNUM* pBNe = BN_new();
- BN_set_word(pBNe, RSA_3);
- int ret = RSA_generate_key_ex(pRSA, 512, pBNe, NULL);
- printf("RSA_generate_key_ex() ret:%d \n", ret);
- BN_free(pBNe);
- RSA_print_fp(stdout, pRSA , 0);
-
- RSA* pRSApub = RSAPublicKey_dup(pRSA);
- printf("copy pub key:%p \n", pRSApub);
- RSA_print_fp(stdout, pRSApub , 0);
- RSA_free(pRSApub);
- RSA* pRSApri = RSAPrivateKey_dup(pRSA);
- printf("copy pri key:%p \n", pRSApri);
- RSA_print_fp(stdout, pRSApri , 0);
- RSA_free(pRSApri);
-
- int bits = RSA_bits(pRSA);
- printf("bits:%d \n", bits);
- int bytes = RSA_size(pRSA);
- printf("bytes:%d \n", bytes);
-
- ret = RSA_check_key(pRSA);
- printf("RSA_check_key() ret:%d \n", ret);
-
- char sText[] = "1234567890";
-
- unsigned char* pCipher = (unsigned char*)malloc(bytes);
- ret = RSA_public_encrypt(strlen(sText), (const unsigned char*)sText, pCipher, pRSA, RSA_PKCS1_PADDING);
- printf("RSA_public_encrypt() ret:%d \n", ret);
- if (ret <= 0)
- {
- unsigned long err = ERR_get_error();
- printf("err:[%ld] \n", err);
- char sBuf[128] = {0};
- char* pErrStr = ERR_error_string(err, sBuf);
- printf("errstr:[%s] \n", pErrStr);
- }
-
- unsigned char* pText = (unsigned char*)malloc(bytes);
- ret = RSA_private_decrypt(ret, (const unsigned char*)pCipher, pText, pRSA, RSA_PKCS1_PADDING);
- printf("RSA_private_decrypt() ret:%d \n", ret);
- if (ret > 0)
- {
- printf("text:[%s] \n", pText);
- }
-
- free(pCipher);
- free(pText);
-
- RSA_free(pRSA);
-
- return 0;
- }
输出:
- RSA Private-Key: (512 bit, 2 primes)
- modulus:
- 00:9f:d4:b7:53:c9:22:30:8d:52:31:13:67:61:ce:
- 12:bc:25:85:44:94:0e:87:e2:b9:8c:87:dd:ca:d0:
- df:1c:84:51:c7:ac:ec:a3:3f:2b:48:81:74:18:22:
- 9a:c2:a8:11:03:8c:19:b6:a6:45:2d:81:d4:18:65:
- bb:90:59:e6:d5
- publicExponent: 3 (0x3)
- privateExponent:
- 6a:8d:cf:8d:30:c1:75:b3:8c:20:b7:9a:41:34:0c:
- 7d:6e:58:d8:62:b4:5a:97:26:5d:af:e9:31:e0:94:
- bd:ac:7d:e2:9e:a3:b3:4c:e9:23:41:bf:3c:ca:4d:
- 3e:ee:b6:f5:36:1c:7a:9c:2d:70:e3:20:94:53:b6:
- e9:0a:13:eb
- prime1:
- 00:d3:69:55:a1:b4:24:1d:11:56:18:3e:b4:bf:06:
- 23:05:69:d2:12:78:1e:b5:45:47:8c:3f:8a:6e:02:
- 48:d5:4d
- prime2:
- 00:c1:8a:69:55:62:27:b0:82:48:bc:fe:3e:67:de:
- 1e:f9:29:e8:dc:86:9d:4b:be:e5:96:fa:5d:bb:30:
- 81:f3:a9
- exponent1:
- 00:8c:f0:e3:c1:22:c2:be:0b:8e:ba:d4:78:7f:59:
- 6c:ae:46:8c:0c:50:14:78:d8:da:5d:7f:b1:9e:ac:
- 30:8e:33
- exponent2:
- 00:81:06:f0:e3:96:c5:20:56:db:28:a9:7e:ef:e9:
- 69:fb:71:45:e8:59:be:32:7f:43:b9:fc:3e:7c:cb:
- 01:4d:1b
- coefficient:
- 00:cb:09:a1:95:b6:64:0c:d0:50:50:58:cb:20:fd:
- bc:7c:e6:fb:56:22:73:75:34:7b:44:6d:a5:94:87:
- 59:8f:58
- RSA_generate_key_ex() ret:1
- RSA Private-Key: (512 bit, 2 primes)
- modulus:
- 00:ac:3b:05:ad:53:48:42:fb:8e:a0:52:53:29:71:
- 3b:30:a6:47:74:99:7b:9f:94:48:93:92:1f:57:78:
- 01:07:6c:db:bd:34:f0:c9:35:42:7e:20:c1:ec:94:
- 7d:0b:cc:c7:70:56:52:87:cc:04:66:30:4b:06:fb:
- 49:ee:78:eb:af
- publicExponent: 3 (0x3)
- privateExponent:
- 72:d2:03:c8:e2:30:2c:a7:b4:6a:e1:8c:c6:4b:7c:
- cb:19:84:f8:66:52:6a:62:db:0d:0c:14:e4:fa:ab:
- 5a:47:7a:64:2a:7b:1c:27:0b:c2:37:a0:7f:52:fc:
- 53:17:3e:ba:9f:cb:0b:4d:5b:94:0f:38:f1:97:67:
- eb:d7:a3:ab
- prime1:
- 00:d8:79:81:07:43:58:8f:a7:ab:db:04:bf:e5:a0:
- 03:35:7c:13:76:5b:22:2c:de:e0:c7:29:4b:66:65:
- e3:aa:ef
- prime2:
- 00:cb:ad:74:30:db:a2:21:33:21:76:28:d8:1c:ef:
- 26:b3:dc:53:2b:9b:b5:ce:29:38:ae:73:4c:c7:a6:
- d1:cb:41
- exponent1:
- 00:90:51:00:af:82:3b:0a:6f:c7:e7:58:7f:ee:6a:
- ac:ce:52:b7:a4:3c:c1:73:3f:40:84:c6:32:44:43:
- ed:1c:9f
- exponent2:
- 00:87:c8:f8:20:92:6c:16:22:16:4e:c5:e5:68:9f:
- 6f:22:92:e2:1d:12:79:34:1b:7b:1e:f7:88:85:19:
- e1:32:2b
- coefficient:
- 00:bd:69:e1:82:71:0e:e3:e6:bb:c3:55:2a:10:f7:
- b1:26:1e:c2:9a:d7:44:9f:88:be:aa:3e:7d:d1:7c:
- c0:94:ba
- copy pub key:0x203f770
- RSA Public-Key: (512 bit)
- Modulus:
- 00:ac:3b:05:ad:53:48:42:fb:8e:a0:52:53:29:71:
- 3b:30:a6:47:74:99:7b:9f:94:48:93:92:1f:57:78:
- 01:07:6c:db:bd:34:f0:c9:35:42:7e:20:c1:ec:94:
- 7d:0b:cc:c7:70:56:52:87:cc:04:66:30:4b:06:fb:
- 49:ee:78:eb:af
- Exponent: 3 (0x3)
- copy pri key:0x203f770
- RSA Private-Key: (512 bit, 2 primes)
- modulus:
- 00:ac:3b:05:ad:53:48:42:fb:8e:a0:52:53:29:71:
- 3b:30:a6:47:74:99:7b:9f:94:48:93:92:1f:57:78:
- 01:07:6c:db:bd:34:f0:c9:35:42:7e:20:c1:ec:94:
- 7d:0b:cc:c7:70:56:52:87:cc:04:66:30:4b:06:fb:
- 49:ee:78:eb:af
- publicExponent: 3 (0x3)
- privateExponent:
- 72:d2:03:c8:e2:30:2c:a7:b4:6a:e1:8c:c6:4b:7c:
- cb:19:84:f8:66:52:6a:62:db:0d:0c:14:e4:fa:ab:
- 5a:47:7a:64:2a:7b:1c:27:0b:c2:37:a0:7f:52:fc:
- 53:17:3e:ba:9f:cb:0b:4d:5b:94:0f:38:f1:97:67:
- eb:d7:a3:ab
- prime1:
- 00:d8:79:81:07:43:58:8f:a7:ab:db:04:bf:e5:a0:
- 03:35:7c:13:76:5b:22:2c:de:e0:c7:29:4b:66:65:
- e3:aa:ef
- prime2:
- 00:cb:ad:74:30:db:a2:21:33:21:76:28:d8:1c:ef:
- 26:b3:dc:53:2b:9b:b5:ce:29:38:ae:73:4c:c7:a6:
- d1:cb:41
- exponent1:
- 00:90:51:00:af:82:3b:0a:6f:c7:e7:58:7f:ee:6a:
- ac:ce:52:b7:a4:3c:c1:73:3f:40:84:c6:32:44:43:
- ed:1c:9f
- exponent2:
- 00:87:c8:f8:20:92:6c:16:22:16:4e:c5:e5:68:9f:
- 6f:22:92:e2:1d:12:79:34:1b:7b:1e:f7:88:85:19:
- e1:32:2b
- coefficient:
- 00:bd:69:e1:82:71:0e:e3:e6:bb:c3:55:2a:10:f7:
- b1:26:1e:c2:9a:d7:44:9f:88:be:aa:3e:7d:d1:7c:
- c0:94:ba
- bits:512
- bytes:64
- RSA_check_key() ret:1
- RSA_public_encrypt() ret:64
- RSA_private_decrypt() ret:10
- text:[1234567890]
下面这个例子演示了公私钥的分开保存、读取,以及使用公私钥加解密。
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
-
- #include <openssl/rsa.h>
- #include <openssl/err.h>
- #include <openssl/x509.h>
-
- namespace dakuang {}
-
- int main(int argc, char* argv[])
- {
- ERR_load_RSA_strings();
-
- RSA* pRSA = RSA_new();
- BIGNUM* pBNe = BN_new();
- BN_set_word(pBNe, RSA_3);
- int ret = RSA_generate_key_ex(pRSA, 512, pBNe, NULL);
- printf("RSA_generate_key_ex() ret:%d \n", ret);
- BN_free(pBNe);
-
- BIO* pBIOpri = BIO_new_file("rsa.key","w");
- BIO* pBIOpub = BIO_new_file("rsa.pub","w");
- ret = i2d_RSAPrivateKey_bio(pBIOpri, pRSA);
- printf("i2d_RSAPrivateKey_bio() ret:%d \n", ret);
- ret = i2d_RSAPublicKey_bio(pBIOpub, pRSA);
- printf("i2d_RSAPublicKey_bio() ret:%d \n", ret);
- BIO_free(pBIOpri);
- BIO_free(pBIOpub);
-
- RSA* pRSApri = RSA_new();
- RSA* pRSApub = RSA_new();
- BIO* pBIOpri2 = BIO_new_file("rsa.key","r");
- BIO* pBIOpub2 = BIO_new_file("rsa.pub","r");
- d2i_RSAPrivateKey_bio(pBIOpri2, &pRSApri);
- d2i_RSAPublicKey_bio(pBIOpub2, &pRSApub);
- BIO_free(pBIOpri2);
- BIO_free(pBIOpub2);
-
- int bytes = RSA_size(pRSApri);
- printf("copy' private key size:%d \n", bytes);
- int bytes2 = RSA_size(pRSApub);
- printf("copy' public key size:%d \n", bytes2);
-
- char sText[] = "1234567890";
-
- unsigned char* pCipher = (unsigned char*)malloc(bytes);
- ret = RSA_public_encrypt(strlen(sText), (const unsigned char*)sText, pCipher, pRSApub, RSA_PKCS1_PADDING);
- printf("RSA_public_encrypt() ret:%d \n", ret);
- if (ret <= 0)
- {
- unsigned long err = ERR_get_error();
- printf("err:[%ld] \n", err);
- char sBuf[128] = {0};
- char* pErrStr = ERR_error_string(err, sBuf);
- printf("errstr:[%s] \n", pErrStr);
- }
-
- unsigned char* pText = (unsigned char*)malloc(bytes);
- ret = RSA_private_decrypt(ret, (const unsigned char*)pCipher, pText, pRSApri, RSA_PKCS1_PADDING);
- printf("RSA_private_decrypt() ret:%d \n", ret);
- if (ret > 0)
- {
- printf("text:[%s] \n", pText);
- }
- free(pCipher);
- free(pText);
-
- RSA_free(pRSApri);
- RSA_free(pRSApub);
- RSA_free(pRSA);
-
- return 0;
- }
输出:
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]
下面这个例子演示了签名的生成和验证操作。
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
-
- #include <openssl/rsa.h>
- #include <openssl/err.h>
- #include <openssl/objects.h>
-
- namespace dakuang {}
-
- void printHex(const unsigned char* pBuf, int nLen)
- {
- for (int i = 0; i < nLen; ++i)
- {
- printf("%02x", pBuf[i]);
- }
- printf("\n");
- }
-
- int main(int argc, char* argv[])
- {
- ERR_load_RSA_strings();
-
- RSA* pRSA = RSA_new();
- BIGNUM* pBNe = BN_new();
- BN_set_word(pBNe, RSA_3);
- int ret = RSA_generate_key_ex(pRSA, 512, pBNe, NULL);
- printf("ret:%d \n", ret);
- BN_free(pBNe);
-
- char sData[] = "1234567890";
- char sSign[512] = {0};
- unsigned int nSignLen = 512;
- ret = RSA_sign(NID_sha1, (unsigned char *)sData, 10, (unsigned char *)sSign, &nSignLen, pRSA);
- printf("RSA_sign() ret:%d \n", ret);
- printf("sign %d \n", nSignLen);
- printHex((const unsigned char*)sSign, nSignLen);
-
- //sSign[0] = 0;
- ret = RSA_verify(NID_sha1, (unsigned char *)sData, 10, (unsigned char *)sSign, nSignLen, pRSA);
- printf("RSA_verify() ret:%d \n", ret);
-
- RSA_free(pRSA);
-
- return 0;
- }
输出:
ret:1
RSA_sign() ret:1
sign 64
4ec0af099c49646b72fda88a4fb11e8deb3898da9c3f611a5f25f05d9d005631858239bbb732cd5060dbc975363fc1b9cdfdc5a04554115a916f06f98163189f
RSA_verify() ret:1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。