当前位置:   article > 正文

OpenSSL之RSA用法_openssl rsa

openssl rsa

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目录中。

主要结构:

  1. struct rsa_st {
  2. /*
  3. * The first parameter is used to pickup errors where this is passed
  4. * instead of an EVP_PKEY, it is set to 0
  5. */
  6. int pad;
  7. int32_t version;
  8. const RSA_METHOD *meth;
  9. /* functional reference if 'meth' is ENGINE-provided */
  10. ENGINE *engine;
  11. BIGNUM *n;
  12. BIGNUM *e;
  13. BIGNUM *d;
  14. BIGNUM *p;
  15. BIGNUM *q;
  16. BIGNUM *dmp1;
  17. BIGNUM *dmq1;
  18. BIGNUM *iqmp;
  19. /* for multi-prime RSA, defined in RFC 8017 */
  20. STACK_OF(RSA_PRIME_INFO) *prime_infos;
  21. /* If a PSS only key this contains the parameter restrictions */
  22. RSA_PSS_PARAMS *pss;
  23. /* be careful using this if the RSA structure is shared */
  24. CRYPTO_EX_DATA ex_data;
  25. CRYPTO_REF_COUNT references;
  26. int flags;
  27. /* Used to cache montgomery values */
  28. BN_MONT_CTX *_method_mod_n;
  29. BN_MONT_CTX *_method_mod_p;
  30. BN_MONT_CTX *_method_mod_q;
  31. /*
  32. * all BIGNUM values are actually in the following data, if it is not
  33. * NULL
  34. */
  35. char *bignum_data;
  36. BN_BLINDING *blinding;
  37. BN_BLINDING *mt_blinding;
  38. CRYPTO_RWLOCK *lock;
  39. };
  40. typedef struct rsa_st RSA;

这个结构定义了RSA内部数据信息。主要字段含义:
version —— 版本。
meth —— RSA运算抽象方法集合。
n,e,d,p,q,dmp1,dmq1,iqmp —— 密钥相关的大数。

  1. struct rsa_meth_st {
  2. char *name;
  3. int (*rsa_pub_enc) (int flen, const unsigned char *from,
  4. unsigned char *to, RSA *rsa, int padding);
  5. int (*rsa_pub_dec) (int flen, const unsigned char *from,
  6. unsigned char *to, RSA *rsa, int padding);
  7. int (*rsa_priv_enc) (int flen, const unsigned char *from,
  8. unsigned char *to, RSA *rsa, int padding);
  9. int (*rsa_priv_dec) (int flen, const unsigned char *from,
  10. unsigned char *to, RSA *rsa, int padding);
  11. /* Can be null */
  12. int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
  13. /* Can be null */
  14. int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  15. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  16. /* called at new */
  17. int (*init) (RSA *rsa);
  18. /* called at free */
  19. int (*finish) (RSA *rsa);
  20. /* RSA_METHOD_FLAG_* things */
  21. int flags;
  22. /* may be needed! */
  23. char *app_data;
  24. /*
  25. * New sign and verify functions: some libraries don't allow arbitrary
  26. * data to be signed/verified: this allows them to be used. Note: for
  27. * this to work the RSA_public_decrypt() and RSA_private_encrypt() should
  28. * *NOT* be used RSA_sign(), RSA_verify() should be used instead.
  29. */
  30. int (*rsa_sign) (int type,
  31. const unsigned char *m, unsigned int m_length,
  32. unsigned char *sigret, unsigned int *siglen,
  33. const RSA *rsa);
  34. int (*rsa_verify) (int dtype, const unsigned char *m,
  35. unsigned int m_length, const unsigned char *sigbuf,
  36. unsigned int siglen, const RSA *rsa);
  37. /*
  38. * If this callback is NULL, the builtin software RSA key-gen will be
  39. * used. This is for behavioural compatibility whilst the code gets
  40. * rewired, but one day it would be nice to assume there are no such
  41. * things as "builtin software" implementations.
  42. */
  43. int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
  44. int (*rsa_multi_prime_keygen) (RSA *rsa, int bits, int primes,
  45. BIGNUM *e, BN_GENCB *cb);
  46. };
  47. 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填充方式,取值:

  1. # define RSA_PKCS1_PADDING 1
  2. # define RSA_SSLV23_PADDING 2
  3. # define RSA_NO_PADDING 3
  4. # define RSA_PKCS1_OAEP_PADDING 4
  5. # define RSA_X931_PADDING 5
  6. /* EVP_PKEY_ only */
  7. # 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中定义:

  1. int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
  2. {
  3. return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
  4. }

将RSA公钥转换为DER编码,并写入到bp抽象IO中。
成功返回1,失败返回0。

  1. RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
  2. {
  3. return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
  4. }

从bp抽象IO中读取DER编码,并转换为rsa结构私钥。
成功返回有效指定,失败返回NULL。

  1. int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
  2. {
  3. return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
  4. }

将RSA公钥转换为DER编码,并写入到bp抽象IO中。
成功返回1,失败返回0。

  1. RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
  2. {
  3. return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
  4. }

从bp抽象IO中读取DER编码,并转换为rsa结构公钥。
成功返回有效指定,失败返回NULL。

使用举例1:

下面这个例子演示了RSA密钥对的生成、公私钥的复制、公钥加密和私钥解密的用法。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <openssl/rsa.h>
  6. #include <openssl/err.h>
  7. namespace dakuang {}
  8. int main(int argc, char* argv[])
  9. {
  10. ERR_load_RSA_strings();
  11. RSA* pRSA = RSA_generate_key(512, RSA_3, NULL, NULL);
  12. RSA_print_fp(stdout, pRSA , 0);
  13. RSA_free(pRSA);
  14. pRSA = RSA_new();
  15. BIGNUM* pBNe = BN_new();
  16. BN_set_word(pBNe, RSA_3);
  17. int ret = RSA_generate_key_ex(pRSA, 512, pBNe, NULL);
  18. printf("RSA_generate_key_ex() ret:%d \n", ret);
  19. BN_free(pBNe);
  20. RSA_print_fp(stdout, pRSA , 0);
  21. RSA* pRSApub = RSAPublicKey_dup(pRSA);
  22. printf("copy pub key:%p \n", pRSApub);
  23. RSA_print_fp(stdout, pRSApub , 0);
  24. RSA_free(pRSApub);
  25. RSA* pRSApri = RSAPrivateKey_dup(pRSA);
  26. printf("copy pri key:%p \n", pRSApri);
  27. RSA_print_fp(stdout, pRSApri , 0);
  28. RSA_free(pRSApri);
  29. int bits = RSA_bits(pRSA);
  30. printf("bits:%d \n", bits);
  31. int bytes = RSA_size(pRSA);
  32. printf("bytes:%d \n", bytes);
  33. ret = RSA_check_key(pRSA);
  34. printf("RSA_check_key() ret:%d \n", ret);
  35. char sText[] = "1234567890";
  36. unsigned char* pCipher = (unsigned char*)malloc(bytes);
  37. ret = RSA_public_encrypt(strlen(sText), (const unsigned char*)sText, pCipher, pRSA, RSA_PKCS1_PADDING);
  38. printf("RSA_public_encrypt() ret:%d \n", ret);
  39. if (ret <= 0)
  40. {
  41. unsigned long err = ERR_get_error();
  42. printf("err:[%ld] \n", err);
  43. char sBuf[128] = {0};
  44. char* pErrStr = ERR_error_string(err, sBuf);
  45. printf("errstr:[%s] \n", pErrStr);
  46. }
  47. unsigned char* pText = (unsigned char*)malloc(bytes);
  48. ret = RSA_private_decrypt(ret, (const unsigned char*)pCipher, pText, pRSA, RSA_PKCS1_PADDING);
  49. printf("RSA_private_decrypt() ret:%d \n", ret);
  50. if (ret > 0)
  51. {
  52. printf("text:[%s] \n", pText);
  53. }
  54. free(pCipher);
  55. free(pText);
  56. RSA_free(pRSA);
  57. return 0;
  58. }

输出:

  1. RSA Private-Key: (512 bit, 2 primes)
  2. modulus:
  3. 00:9f:d4:b7:53:c9:22:30:8d:52:31:13:67:61:ce:
  4. 12:bc:25:85:44:94:0e:87:e2:b9:8c:87:dd:ca:d0:
  5. df:1c:84:51:c7:ac:ec:a3:3f:2b:48:81:74:18:22:
  6. 9a:c2:a8:11:03:8c:19:b6:a6:45:2d:81:d4:18:65:
  7. bb:90:59:e6:d5
  8. publicExponent: 3 (0x3)
  9. privateExponent:
  10. 6a:8d:cf:8d:30:c1:75:b3:8c:20:b7:9a:41:34:0c:
  11. 7d:6e:58:d8:62:b4:5a:97:26:5d:af:e9:31:e0:94:
  12. bd:ac:7d:e2:9e:a3:b3:4c:e9:23:41:bf:3c:ca:4d:
  13. 3e:ee:b6:f5:36:1c:7a:9c:2d:70:e3:20:94:53:b6:
  14. e9:0a:13:eb
  15. prime1:
  16. 00:d3:69:55:a1:b4:24:1d:11:56:18:3e:b4:bf:06:
  17. 23:05:69:d2:12:78:1e:b5:45:47:8c:3f:8a:6e:02:
  18. 48:d5:4d
  19. prime2:
  20. 00:c1:8a:69:55:62:27:b0:82:48:bc:fe:3e:67:de:
  21. 1e:f9:29:e8:dc:86:9d:4b:be:e5:96:fa:5d:bb:30:
  22. 81:f3:a9
  23. exponent1:
  24. 00:8c:f0:e3:c1:22:c2:be:0b:8e:ba:d4:78:7f:59:
  25. 6c:ae:46:8c:0c:50:14:78:d8:da:5d:7f:b1:9e:ac:
  26. 30:8e:33
  27. exponent2:
  28. 00:81:06:f0:e3:96:c5:20:56:db:28:a9:7e:ef:e9:
  29. 69:fb:71:45:e8:59:be:32:7f:43:b9:fc:3e:7c:cb:
  30. 01:4d:1b
  31. coefficient:
  32. 00:cb:09:a1:95:b6:64:0c:d0:50:50:58:cb:20:fd:
  33. bc:7c:e6:fb:56:22:73:75:34:7b:44:6d:a5:94:87:
  34. 59:8f:58
  35. RSA_generate_key_ex() ret:1
  36. RSA Private-Key: (512 bit, 2 primes)
  37. modulus:
  38. 00:ac:3b:05:ad:53:48:42:fb:8e:a0:52:53:29:71:
  39. 3b:30:a6:47:74:99:7b:9f:94:48:93:92:1f:57:78:
  40. 01:07:6c:db:bd:34:f0:c9:35:42:7e:20:c1:ec:94:
  41. 7d:0b:cc:c7:70:56:52:87:cc:04:66:30:4b:06:fb:
  42. 49:ee:78:eb:af
  43. publicExponent: 3 (0x3)
  44. privateExponent:
  45. 72:d2:03:c8:e2:30:2c:a7:b4:6a:e1:8c:c6:4b:7c:
  46. cb:19:84:f8:66:52:6a:62:db:0d:0c:14:e4:fa:ab:
  47. 5a:47:7a:64:2a:7b:1c:27:0b:c2:37:a0:7f:52:fc:
  48. 53:17:3e:ba:9f:cb:0b:4d:5b:94:0f:38:f1:97:67:
  49. eb:d7:a3:ab
  50. prime1:
  51. 00:d8:79:81:07:43:58:8f:a7:ab:db:04:bf:e5:a0:
  52. 03:35:7c:13:76:5b:22:2c:de:e0:c7:29:4b:66:65:
  53. e3:aa:ef
  54. prime2:
  55. 00:cb:ad:74:30:db:a2:21:33:21:76:28:d8:1c:ef:
  56. 26:b3:dc:53:2b:9b:b5:ce:29:38:ae:73:4c:c7:a6:
  57. d1:cb:41
  58. exponent1:
  59. 00:90:51:00:af:82:3b:0a:6f:c7:e7:58:7f:ee:6a:
  60. ac:ce:52:b7:a4:3c:c1:73:3f:40:84:c6:32:44:43:
  61. ed:1c:9f
  62. exponent2:
  63. 00:87:c8:f8:20:92:6c:16:22:16:4e:c5:e5:68:9f:
  64. 6f:22:92:e2:1d:12:79:34:1b:7b:1e:f7:88:85:19:
  65. e1:32:2b
  66. coefficient:
  67. 00:bd:69:e1:82:71:0e:e3:e6:bb:c3:55:2a:10:f7:
  68. b1:26:1e:c2:9a:d7:44:9f:88:be:aa:3e:7d:d1:7c:
  69. c0:94:ba
  70. copy pub key:0x203f770
  71. RSA Public-Key: (512 bit)
  72. Modulus:
  73. 00:ac:3b:05:ad:53:48:42:fb:8e:a0:52:53:29:71:
  74. 3b:30:a6:47:74:99:7b:9f:94:48:93:92:1f:57:78:
  75. 01:07:6c:db:bd:34:f0:c9:35:42:7e:20:c1:ec:94:
  76. 7d:0b:cc:c7:70:56:52:87:cc:04:66:30:4b:06:fb:
  77. 49:ee:78:eb:af
  78. Exponent: 3 (0x3)
  79. copy pri key:0x203f770
  80. RSA Private-Key: (512 bit, 2 primes)
  81. modulus:
  82. 00:ac:3b:05:ad:53:48:42:fb:8e:a0:52:53:29:71:
  83. 3b:30:a6:47:74:99:7b:9f:94:48:93:92:1f:57:78:
  84. 01:07:6c:db:bd:34:f0:c9:35:42:7e:20:c1:ec:94:
  85. 7d:0b:cc:c7:70:56:52:87:cc:04:66:30:4b:06:fb:
  86. 49:ee:78:eb:af
  87. publicExponent: 3 (0x3)
  88. privateExponent:
  89. 72:d2:03:c8:e2:30:2c:a7:b4:6a:e1:8c:c6:4b:7c:
  90. cb:19:84:f8:66:52:6a:62:db:0d:0c:14:e4:fa:ab:
  91. 5a:47:7a:64:2a:7b:1c:27:0b:c2:37:a0:7f:52:fc:
  92. 53:17:3e:ba:9f:cb:0b:4d:5b:94:0f:38:f1:97:67:
  93. eb:d7:a3:ab
  94. prime1:
  95. 00:d8:79:81:07:43:58:8f:a7:ab:db:04:bf:e5:a0:
  96. 03:35:7c:13:76:5b:22:2c:de:e0:c7:29:4b:66:65:
  97. e3:aa:ef
  98. prime2:
  99. 00:cb:ad:74:30:db:a2:21:33:21:76:28:d8:1c:ef:
  100. 26:b3:dc:53:2b:9b:b5:ce:29:38:ae:73:4c:c7:a6:
  101. d1:cb:41
  102. exponent1:
  103. 00:90:51:00:af:82:3b:0a:6f:c7:e7:58:7f:ee:6a:
  104. ac:ce:52:b7:a4:3c:c1:73:3f:40:84:c6:32:44:43:
  105. ed:1c:9f
  106. exponent2:
  107. 00:87:c8:f8:20:92:6c:16:22:16:4e:c5:e5:68:9f:
  108. 6f:22:92:e2:1d:12:79:34:1b:7b:1e:f7:88:85:19:
  109. e1:32:2b
  110. coefficient:
  111. 00:bd:69:e1:82:71:0e:e3:e6:bb:c3:55:2a:10:f7:
  112. b1:26:1e:c2:9a:d7:44:9f:88:be:aa:3e:7d:d1:7c:
  113. c0:94:ba
  114. bits:512
  115. bytes:64
  116. RSA_check_key() ret:1
  117. RSA_public_encrypt() ret:64
  118. RSA_private_decrypt() ret:10
  119. text:[1234567890]

使用举例2:

下面这个例子演示了公私钥的分开保存、读取,以及使用公私钥加解密。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <openssl/rsa.h>
  6. #include <openssl/err.h>
  7. #include <openssl/x509.h>
  8. namespace dakuang {}
  9. int main(int argc, char* argv[])
  10. {
  11. ERR_load_RSA_strings();
  12. RSA* pRSA = RSA_new();
  13. BIGNUM* pBNe = BN_new();
  14. BN_set_word(pBNe, RSA_3);
  15. int ret = RSA_generate_key_ex(pRSA, 512, pBNe, NULL);
  16. printf("RSA_generate_key_ex() ret:%d \n", ret);
  17. BN_free(pBNe);
  18. BIO* pBIOpri = BIO_new_file("rsa.key","w");
  19. BIO* pBIOpub = BIO_new_file("rsa.pub","w");
  20. ret = i2d_RSAPrivateKey_bio(pBIOpri, pRSA);
  21. printf("i2d_RSAPrivateKey_bio() ret:%d \n", ret);
  22. ret = i2d_RSAPublicKey_bio(pBIOpub, pRSA);
  23. printf("i2d_RSAPublicKey_bio() ret:%d \n", ret);
  24. BIO_free(pBIOpri);
  25. BIO_free(pBIOpub);
  26. RSA* pRSApri = RSA_new();
  27. RSA* pRSApub = RSA_new();
  28. BIO* pBIOpri2 = BIO_new_file("rsa.key","r");
  29. BIO* pBIOpub2 = BIO_new_file("rsa.pub","r");
  30. d2i_RSAPrivateKey_bio(pBIOpri2, &pRSApri);
  31. d2i_RSAPublicKey_bio(pBIOpub2, &pRSApub);
  32. BIO_free(pBIOpri2);
  33. BIO_free(pBIOpub2);
  34. int bytes = RSA_size(pRSApri);
  35. printf("copy' private key size:%d \n", bytes);
  36. int bytes2 = RSA_size(pRSApub);
  37. printf("copy' public key size:%d \n", bytes2);
  38. char sText[] = "1234567890";
  39. unsigned char* pCipher = (unsigned char*)malloc(bytes);
  40. ret = RSA_public_encrypt(strlen(sText), (const unsigned char*)sText, pCipher, pRSApub, RSA_PKCS1_PADDING);
  41. printf("RSA_public_encrypt() ret:%d \n", ret);
  42. if (ret <= 0)
  43. {
  44. unsigned long err = ERR_get_error();
  45. printf("err:[%ld] \n", err);
  46. char sBuf[128] = {0};
  47. char* pErrStr = ERR_error_string(err, sBuf);
  48. printf("errstr:[%s] \n", pErrStr);
  49. }
  50. unsigned char* pText = (unsigned char*)malloc(bytes);
  51. ret = RSA_private_decrypt(ret, (const unsigned char*)pCipher, pText, pRSApri, RSA_PKCS1_PADDING);
  52. printf("RSA_private_decrypt() ret:%d \n", ret);
  53. if (ret > 0)
  54. {
  55. printf("text:[%s] \n", pText);
  56. }
  57. free(pCipher);
  58. free(pText);
  59. RSA_free(pRSApri);
  60. RSA_free(pRSApub);
  61. RSA_free(pRSA);
  62. return 0;
  63. }

输出:
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]

使用举例3:

下面这个例子演示了签名的生成和验证操作。


 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <openssl/rsa.h>
  6. #include <openssl/err.h>
  7. #include <openssl/objects.h>
  8. namespace dakuang {}
  9. void printHex(const unsigned char* pBuf, int nLen)
  10. {
  11. for (int i = 0; i < nLen; ++i)
  12. {
  13. printf("%02x", pBuf[i]);
  14. }
  15. printf("\n");
  16. }
  17. int main(int argc, char* argv[])
  18. {
  19. ERR_load_RSA_strings();
  20. RSA* pRSA = RSA_new();
  21. BIGNUM* pBNe = BN_new();
  22. BN_set_word(pBNe, RSA_3);
  23. int ret = RSA_generate_key_ex(pRSA, 512, pBNe, NULL);
  24. printf("ret:%d \n", ret);
  25. BN_free(pBNe);
  26. char sData[] = "1234567890";
  27. char sSign[512] = {0};
  28. unsigned int nSignLen = 512;
  29. ret = RSA_sign(NID_sha1, (unsigned char *)sData, 10, (unsigned char *)sSign, &nSignLen, pRSA);
  30. printf("RSA_sign() ret:%d \n", ret);
  31. printf("sign %d \n", nSignLen);
  32. printHex((const unsigned char*)sSign, nSignLen);
  33. //sSign[0] = 0;
  34. ret = RSA_verify(NID_sha1, (unsigned char *)sData, 10, (unsigned char *)sSign, nSignLen, pRSA);
  35. printf("RSA_verify() ret:%d \n", ret);
  36. RSA_free(pRSA);
  37. return 0;
  38. }

输出:
ret:1
RSA_sign() ret:1

sign 64
4ec0af099c49646b72fda88a4fb11e8deb3898da9c3f611a5f25f05d9d005631858239bbb732cd5060dbc975363fc1b9cdfdc5a04554115a916f06f98163189f

RSA_verify() ret:1

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/308327
推荐阅读
相关标签
  

闽ICP备14008679号