openssl 非对称加密 RSA 加密解密以及签名验证签名
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 = ;
BIGNUM *e = BN_new();
BN_set_word(e, );
RSA_generate_key_ex(r, bits, e, NULL);
//打印密钥
RSA_print_fp(stdout, r, );
打印的密钥对结果:
Private-Key: ( bit)
modulus:
:c0::6c:::ed:4e::bb::ec:be:d6::
:bf:9b:be:4f:8b:fb::ae:f2::9c:e7:b8::
a2::9c::cc:4a:a2::1d:::c8:f6:e0::
3a:::c8:1a:d4:b7::::4c:3b:2a::0b:
:::4f:f9
publicExponent: (0x10001)
privateExponent:
:8f::9e:ca:8f:9f::3a:ed:eb:ec:5a::a0:
c1:2f:::::4c::6a:6e:b8:4a:ab:2c::
:e2:3e:c8:aa::bb::9e:e5:::b4:8f::
::dc:::::::ac::f8:fe:4d::
e1:e2:bf:fd:
prime1:
:fd::4d:f0::a0::5e:d1:c9:0e:b8::f9:
ce:0a:ef::e7:a4:::d8:fd:dd:e6:c4:::
dd:e6:
prime2:
:c2::a9:7b:c8:::::f0::9a::a2:
0b::3b::c0::6d:c6:c7:d1:a1::1d:d3:7d:
:cd:
exponent1:
6c::d8:2a:6b:4f::dd:::::f7:b5:c7:
ad:f2::5b:f7:7b:ca:::0c:eb:d3::f9:ac:
:f5
exponent2:
::e2:5a:::db:1e::2a::3c:6a:e7::
ac:e2:d7:a5::5f::c3:4d:cf::d8::7f::
:9d
coefficient:
:d7:0d:9b:e8:2f:3c::::a0:b2:8b::1d:
e2:b9:0f:9f:ca:b2:::ea:c8:9d:5e::e5:e3:
::aa
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 = ;
unsigned long inLen = strlen(inStr);
int pdBlock = RSA_size(r)-;
unsigned int eCount = (inLen / pdBlock) +;
//分组加密,可以看出outData最大不超过malloc[eCount*pdBlock]
for (int i=; 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 = ;
unsigned long inLen = strlen(inStr);
int pdBlock = RSA_size(r);
unsigned int dCount = inLen / pdBlock;
//分组解密
for (int i=; 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();
//公钥加密
int encRet = kkrsa_public_encrypt(src, encDat, r);
printf("enc:%d\n",encRet); char *decDat = malloc();
//私钥解密
int decRet = kkrsa_private_decrypt(encDat, decDat, r);
printf("dec:%s len=%d\n",decDat,decRet); free(encDat);
free(decDat);
打印结果:
block:
src:this is test encrypt data use RSA_PKCS1_PADDING len=
enc:
dec:this is test encrypt data use RSA_PKCS1_PADDING len= test2
src:this is test private encrypt data use RSA_PKCS1_PADDING len=
enc:
dec:this is test private encrypt data use RSA_PKCS1_PADDI len=
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 = ;
unsigned long inLen = strlen(inStr);
int pdBlock = RSA_size(r)-;
unsigned int eCount = (inLen / pdBlock) +;
//分组加密,可以看出outData最大不超过malloc[eCount*pdBlock]
for (int i=; 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 = ;
unsigned long inLen = strlen(inStr);
int pdBlock = RSA_size(r);
unsigned int dCount = inLen / pdBlock;
//分组解密
for (int i=; 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();
//私钥加密
int encRet2 = kkrsa_private_encrypt(src2, encDat2, r);
printf("enc:%d\n",encRet2); char *decDat2 = malloc();
//公钥解密
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=
enc:
dec:this is test private encrypt data use RSA_PKCS1_PADDING\\\375۷GO\ len=
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 = "";
char *sinDat = malloc(RSA_size(r));
int sinLen = ;
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=
6. 总结
上述RSA分组加密中使用了RSA_PKCS1_PADDING 的补位方式;当然还有如下
不同的补位方式,在进行分组加密时,需要注意分组块的处理
# define RSA_PKCS1_PADDING
# define RSA_SSLV23_PADDING
# define RSA_NO_PADDING
# define RSA_PKCS1_OAEP_PADDING
# define RSA_X931_PADDING
/* EVP_PKEY_ only */
# define RSA_PKCS1_PSS_PADDING # define RSA_PKCS1_PADDING_SIZE
测试使用 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
openssl 非对称加密 RSA 加密解密以及签名验证签名的更多相关文章
- Cryptopp iOS 使用 RSA加密解密和签名验证签名
Cryptopp 是一个c++写的功能完善的密码学工具,类似于openssl 官网:https://www.cryptopp.com 以下主要演示Cryptopp 在iOS上的RSA加密解密签名与验证 ...
- JAVA的非对称加密算法RSA——加密和解密
原文转载至:https://www.cnblogs.com/OnlyCT/p/6586856.html 第一部分:RSA算法原理与加密解密 一.RSA加密过程简述 A和B进行加密通信时,B首先要生成一 ...
- C++调用openssl库生成RSA加密秘钥对
直接上代码.默认生成的是pkcs#1格式 // ---- rsa非对称加解密 ---- // #define KEY_LENGTH 1024 // 密钥长度 #define PUB_KEY_FILE ...
- openssl 非对称加密算法RSA命令详解
1.非对称加密算法概述 非对称加密算法也称公开密钥算法,其解决了对称加密算法密钥分配的问题,非对称加密算法基本特点如下: 1.加密密钥和解密密钥不同 2.密钥对中的一个密钥可以公开 3.根据公开密钥很 ...
- openssl C语言编码实现rsa加密
非原创, 引用自: 1 CC=gcc CPPFLAGS= -I /home/yyx//openssl-1.0.1t/include/ CFLAGS=-Wall -g LIBPATH = -L /usr ...
- 最通俗易懂的RSA加密解密指导
前言 RSA加密算法是一种非对称加密算法,简单来说,就是加密时使用一个钥匙,解密时使用另一个钥匙. 因为加密的钥匙是公开的,所又称公钥,解密的钥匙是不公开的,所以称为私钥. 密钥 关于RSA加密有很多 ...
- MD5,Des,RSA加密解密
一.加密和解密 下面先熟悉几个概念 1>对称加密:加密的key和解密的key是同一个 但是如何确保密钥安全地进行传递?秘钥的安全是一个问题 2>非对称加密:加密点的key和解密的key不是 ...
- 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件
作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...
- RSA非对称加密,使用OpenSSL生成证书,iOS加密,java解密
最近换了一份工作,工作了大概一个多月了吧.差不多得有两个月没有更新博客了吧.在新公司自己写了一个iOS的比较通用的可以架构一个中型应用的不算是框架的一个结构,并已经投入使用.哈哈 说说文章标题的相关的 ...
随机推荐
- jquery 获取父窗口的元素 父窗口 子窗口
一.获取页面元素 取父窗口的元素方法:$(selector, window.parent.document); 那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent ...
- linux shell脚本使用结构化命令
内容: 一.if-then命令 二.if-then-else命令 三.test命令 四.case命令 1.if-then结构化命令中最基本的类型,其格式如下: if command then comm ...
- 如何通过Azure Service Management REST API管理Azure服务
通过本文你将了解: 什么是Azure Service Management REST API 如何获取微软Azure 订阅号 如何获取Azure管理证书 如何调用Azure Service Manag ...
- ClientScript.RegisterStartupScript 不起作用
asp.net webform 使用 ClientScript.RegisterStartupScript 不起作用 form 加上 runat="server",ok
- wex5 实战 图片触摸放大移动插件easyzoom的使用与集成
一 前言 客户的需求就是上帝的召唤. 作为一个开发人员,或者软件从业者,客户的要求就是准则. 遇到一个客户,让我做一个图片放大,但是移动拖拽要定位精准.之前研究过一个hammer插件,多次尝试放大后的 ...
- Paxos算法与Zookeeper分析
1 Paxos算法 1.1 基本定义 算法中的参与者主要分为三个角色,同时每个参与者又可兼领多个角色: ⑴proposer 提出提案,提案信息包括提案编号和提议的value; ⑵acceptor 收到 ...
- String split
这个方法看似简单,其实如果使用不当,会出现很多问题 System.out.println(":ab:cd:ef::".split(":").length);// ...
- [转]ping检测网络连接异常
转载地址:http://blog.csdn.net/feizxiang3/article/details/26672781 一般来说当出现网络无法连接时,习惯性的用ping命令来ping某个ip地址, ...
- (10) 深入了解Java Class文件格式(九)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22432599 经过前八篇关于class文件的博客, 关于class文件格式的内容也基本上讲 ...
- Fragment全解析系列(三):Fragment之我的解决方案:Fragmentation
源码地址:Github,欢迎Star,Fork. Demo网盘下载(V_0.7.13)Demo演示:单Activity + 多Fragment,项目中有3个Demo. 流式的单Activity+多Fr ...