1. 简介

openssl  rsa.h 提供了密码学中公钥加密体系的一些接口,

本文主要讨论利用rsa.h接口开发以下功能

  • 公钥私钥的生成
  • 公钥加密,私钥解密
  • 私钥加密,公钥解密
  • 签名:私钥签名
  • 验证签名:公钥验签

2. 生成公钥私钥对

主要接口,

/* Deprecated version */
DEPRECATEDIN_0_9_8(RSA *RSA_generate_key(int bits, unsigned long e, void(*callback) (int, int, void *),void *cb_arg))/* New version */
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);

接口调用需要先生成一个大数,如下生成密钥对示例

    //生成密钥对RSA *r = RSA_new();int bits = 512;BIGNUM *e = BN_new();BN_set_word(e, 65537);RSA_generate_key_ex(r, bits, e, NULL);//打印密钥RSA_print_fp(stdout, r, 0);

打印的密钥对结果:

Private-Key: (512 bit)
modulus:00:c0:53:6c:46:57:ed:4e:33:bb:71:ec:be:d6:21:78:bf:9b:be:4f:8b:fb:32:ae:f2:83:9c:e7:b8:63:a2:34:9c:98:cc:4a:a2:17:1d:31:03:c8:f6:e0:13:3a:29:40:c8:1a:d4:b7:88:38:07:4c:3b:2a:01:0b:17:45:36:4f:f9
publicExponent: 65537 (0x10001)
privateExponent:00:8f:59:9e:ca:8f:9f:01:3a:ed:eb:ec:5a:11:a0:c1:2f:90:16:39:94:4c:97:6a:6e:b8:4a:ab:2c:74:96:e2:3e:c8:aa:34:bb:99:9e:e5:60:86:b4:8f:55:49:80:dc:26:06:74:13:64:49:ac:31:f8:fe:4d:80:e1:e2:bf:fd:41
prime1:00:fd:95:4d:f0:25:a0:87:5e:d1:c9:0e:b8:96:f9:ce:0a:ef:59:e7:a4:57:49:d8:fd:dd:e6:c4:59:24:dd:e6:33
prime2:00:c2:28:a9:7b:c8:98:97:33:32:f0:52:9a:26:a2:0b:50:3b:86:c0:55:6d:c6:c7:d1:a1:43:1d:d3:7d:53:cd:23
exponent1:6c:80:d8:2a:6b:4f:36:dd:21:92:90:13:f7:b5:c7:ad:f2:20:5b:f7:7b:ca:03:69:0c:eb:d3:13:f9:ac:60:f5
exponent2:55:44:e2:5a:18:98:db:1e:83:2a:84:3c:6a:e7:13:ac:e2:d7:a5:34:5f:87:c3:4d:cf:52:d8:90:7f:24:04:9d
coefficient:00:d7:0d:9b:e8:2f:3c:00:86:00:a0:b2:8b:00:1d:e2:b9:0f:9f:ca:b2:75:84:ea:c8:9d:5e:78:e5:e3:92:46:aa

View Code

3. 公钥加密,私钥解密

主要接口

int RSA_public_encrypt(int flen, const unsigned char *from,unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, const unsigned char *from,unsigned char *to, RSA *rsa, int padding);

由于较长数据需要分组加密,如下封装了一层

//公钥加密
int kkrsa_public_encrypt(char *inStr,char *outData,RSA *r)
{int encRet = 0;unsigned long inLen = strlen(inStr);int pdBlock = RSA_size(r)-11;unsigned int eCount = (inLen / pdBlock) +1;//分组加密,可以看出outData最大不超过malloc[eCount*pdBlock]for (int i=0; i < eCount; i++) {RSA_public_encrypt(inLen > pdBlock?pdBlock:inLen, inStr, outData, r, RSA_PKCS1_PADDING);inStr += pdBlock;outData+=RSA_size(r);encRet+=RSA_size(r);inLen -= pdBlock;}return encRet;
}
//私钥解密
int kkrsa_private_decrypt(char *inStr,char *outData,RSA *r)
{int decRet = 0;unsigned long inLen = strlen(inStr);int pdBlock = RSA_size(r);unsigned int dCount = inLen / pdBlock;//分组解密for (int i=0; i < dCount; i++) {int ret = RSA_private_decrypt(pdBlock, inStr, outData, r, RSA_PKCS1_PADDING);inStr += pdBlock;outData+=ret;decRet+=ret;}return decRet;
}

测试例子,例子中的r,就是上面生成的RSA密钥对,

    //测试一printf("block:%d \n",RSA_size(r));char *src = "this is test encrypt data use RSA_PKCS1_PADDING";printf("src:%s  len=%d\n",src,strlen(src));char *encDat = malloc(1024);//公钥加密int encRet = kkrsa_public_encrypt(src, encDat, r);printf("enc:%d\n",encRet);char *decDat = malloc(1024);//私钥解密int decRet = kkrsa_private_decrypt(encDat, decDat, r);printf("dec:%s  len=%d\n",decDat,decRet);free(encDat);free(decDat);

打印结果:

block:64
src:this is test encrypt data use RSA_PKCS1_PADDING  len=47
enc:64
dec:this is test encrypt data use RSA_PKCS1_PADDING  len=47test2
src:this is test private encrypt data use RSA_PKCS1_PADDING  len=55
enc:128
dec:this is test private encrypt data use RSA_PKCS1_PADDI  len=53

View Code

4. 私钥加密,公钥解密

主要接口

int RSA_private_encrypt(int flen, const unsigned char *from,unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, const unsigned char *from,unsigned char *to, RSA *rsa, int padding);

同样如果数据较长需要进行分组加密,如下简单封装的接口

//私钥加密
int kkrsa_private_encrypt(char *inStr,char *outData,RSA *r)
{int encRet = 0;unsigned long inLen = strlen(inStr);int pdBlock = RSA_size(r)-11;unsigned int eCount = (inLen / pdBlock) +1;//分组加密,可以看出outData最大不超过malloc[eCount*pdBlock]for (int i=0; i < eCount; i++) {RSA_private_encrypt(inLen > pdBlock?pdBlock:inLen, inStr, outData, r, RSA_PKCS1_PADDING);inStr += pdBlock;outData+=RSA_size(r);encRet+=RSA_size(r);inLen -= pdBlock;}return encRet;
}
//公钥解密
int kkrsa_public_decrypt(char *inStr,char *outData,RSA *r)
{int decRet = 0;unsigned long inLen = strlen(inStr);int pdBlock = RSA_size(r);unsigned int dCount = inLen / pdBlock;//分组解密for (int i=0; i < dCount; i++) {int ret = RSA_public_decrypt(pdBlock, inStr, outData, r, RSA_PKCS1_PADDING);inStr += pdBlock;outData+=ret;decRet+=ret;}return decRet;
}

调用示例:需要上面生成的密钥对RSA r

  //测试二printf("\ntest2\n");char *src2 = "this is test private encrypt data use RSA_PKCS1_PADDING";printf("src:%s  len=%d\n",src2,strlen(src2));char *encDat2 = malloc(1024);//私钥加密int encRet2 = kkrsa_private_encrypt(src2, encDat2, r);printf("enc:%d\n",encRet2);char *decDat2 = malloc(1024);//公钥解密int decRet2 = kkrsa_public_decrypt(encDat2, decDat2, r);printf("dec:%s  len=%d\n",decDat2,decRet2);free(encDat2);free(decDat2);

测试结果:

test2
src:this is test private encrypt data use RSA_PKCS1_PADDING  len=55
enc:128
dec:this is test private encrypt data use RSA_PKCS1_PADDING\372\314\375۷GO\304  len=55

View Code

5. 签名与验证签名

主要接口

int RSA_sign(int type, const unsigned char *m, unsigned int m_length,unsigned char *sigret, unsigned int *siglen, RSA *rsa);
int RSA_verify(int type, const unsigned char *m, unsigned int m_length,const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

测试示例,同样需要上面生成的RSA密钥对

    //签名printf("\ntest sign and verify\n");char *msg = "0123456789";char *sinDat = malloc(RSA_size(r));int sinLen = 0;RSA_sign(NID_sha1, msg,strlen(msg),sinDat,&sinLen, r);int vret = RSA_verify(NID_sha1, msg, strlen(msg), sinDat, sinLen, r);printf("sign_verify=%d\n",vret);

打印结果

test sign and verify
sign_verify=1

View Code

6. 总结

上述RSA分组加密中使用了RSA_PKCS1_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# define RSA_PKCS1_PADDING_SIZE  11

测试使用 openssl 1.1.0c

参考:https://www.openssl.org/docs/man1.0.2/crypto/RSA_public_encrypt.html

https://www.openssl.org/docs/manmaster/man3/RSA_verify.html

转载于:https://www.cnblogs.com/cocoajin/p/6126099.html

openssl 非对称加密 RSA 加密解密以及签名验证签名相关推荐

  1. MacOS下使用C语言基于openssl库进行RSA加密解密

    MacOS下使用C语言基于openssl库进行RSA加密解密 1 安装openssl并生成密钥 首先当然要安装openssl(这里记得看一下安装路径,应该是/usr/local/Cellar/open ...

  2. rsa加密原理数学证明_非对称加密算法——RSA加密原理及数学推导

    说明:原创不易,著作权仅归作者本人所有,转载请注明出处. 建议:建议阅读时间15min+.证明过程可能看着枯燥,需要动手. 一.  RSA是什么? 看到标题的第一瞬间,先想一下,RSA是什么呢?百度百 ...

  3. 非对称加密算法RSA加密传输数据python3源代码实现

    2019独角兽企业重金招聘Python工程师标准>>> import rsa# RSA 算法规定: # 待加密的字节数不能超过密钥的长度值除以 8 再减去 11NBIT = 4096 ...

  4. Java实现非对称加密算法-RSA加解密

    RSA是由三位数学家Rivest.Shamir 和 Adleman 发明的非对称加密算法,这种算法非常可靠,秘钥越长,就越难破解. 目前被破解的最长RSA秘钥是768个二进制位,长度超过768位的秘钥 ...

  5. 前后端跨语言RSA加解密和签名验证实现(js+python)

    信息安全课程作业,敲了整整4天才基本搞定,还有一小问题没解决,可以的话评论区留言感激不尽. 总体思路: 该系统后端使用python的tornado框架(专门实现聊天功能的框架,笔者也只学了一天),前端 ...

  6. Python加密—RSA加密

    为什么80%的码农都做不了架构师?>>> 公钥加密,私钥解密. import rsa import base64 from Crypto.PublicKey import RSA # ...

  7. token加密——RSA加密

    RSA加密工具类 RsaUtils.java package com.hahashujia.utils;import lombok.extern.slf4j.Slf4j; import org.apa ...

  8. 非对称加密算法--RSA加密原理及运用

    密码学是在编码与破译的斗争实践中逐步发展起来的,并随着先进科学技术的应用,已成为一门综合性的尖端技术科学. 密码学发展史 在说RSA加密算法之前, 先说下密码学的发展史.其实密码学的诞生,就是为了运用 ...

  9. 用c语言elgamal共密钥密码加密算法,非对称密钥体制RSA加密原理

    一.非对称密钥加密概述 前面讲述了对称密钥加密体制.使用对称密钥加密体制进行保密通信时,任意不同的两个用户之间都应该使用互不相同的密钥.这样,如果一个网络中有n个用户,他们之间彼此都可能进行秘密通信, ...

最新文章

  1. 【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )
  2. git上传代码到码云(详细)
  3. 阿里开源那个牛哄哄问题排查工具竟然不会用?最佳实践来了!
  4. JavaScript通过RegExp实现客户端验证
  5. 微信小程序多选取值判断显示内容
  6. 会计转行从事IT,如何在一年时间内全职学习?
  7. Python基础—06-函数基础
  8. scrapy立面parse_立面设计模式–设计观点
  9. JDBC教程– ULTIMATE指南(PDF下载)
  10. mysql 5.7 pxc_mysql5.7 PXC安装记录
  11. Markdown生成左边框目录
  12. Swift - 设置应用程序图标的提醒个数(右上角小红圈)
  13. 软件项目进度控制表(自制)
  14. 小程序 房租水电费记录管理_收租小程序开发有哪些功能和优势?
  15. esxi安装报错解决方案
  16. 使用python快速插入一百万数据
  17. 微信小程序加载闪屏,黑白屏,闪退问题
  18. 为何大数据在国内“雷声大雨点小”
  19. 允许应用更改计算机,解决电脑总弹出“是否允许程序对计算机进行更改”
  20. HBuilderX用uni-app做微信小程序授权登录

热门文章

  1. 【Android基础】点击Back键退出应用程序
  2. LockBits in GDI+【转】http://timothyqiu.com/archives/lockbits-in-gdiplus/
  3. Android入门:实现一个File存储的辅助类
  4. FTP资源下检测URL地址下文件大小
  5. 升级 90天 vs2008 在win2008下。
  6. POJ 3461 KMP
  7. 【Android Gradle 插件】ProductFlavor 配置 ( ProductFlavor#manifestPlaceholders 清单文件占位符配置 )
  8. 【数字信号处理】傅里叶变换性质 ( 傅里叶变换频移性质示例 )
  9. 【Flutter】Flutter 开源项目参考
  10. 【计算理论】计算理论总结 ( 正则表达式转为非确定性有限自动机 NFA ) ★★