OPENSSL库的使用-RSA篇

2023-10-27

一、RSA算法简介

        RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
       RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
       RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
 
二、RSA算法加解密用到的函数
1、RSA基本结构
struct
 
        {
 
          int pad;
 
          long version;
 
          const RSA_METHOD *meth;
 
          ENGINE *engine;
 
          BIGNUM *n;                n=p*q
 
          BIGNUM *e;                公开的加密指数,经常为65537(ox10001)
 
          BIGNUM *d;                私钥
 
          BIGNUM *p;                大素数p
 
          BIGNUM *q;                大素数q
 
          BIGNUM *dmp1;          d mod (p-1)
 
          BIGNUM *dmq1;          d mod (q-1)
 
          BIGNUM *iqmp;          (inverse of q) mod p
 
          int references;
 
          int flags;
 
              // ...
 
          }RSA;
2、初始化函数
RSA * RSA_new(void);初始化一个RSA结构

3、RSA私钥产生函数
RSA *RSA_generate_key(int num, unsigned long e,void (*callback)(int,int,void *), void *cb_arg);产生一个模为num位的密钥对,e为公开的加密指数,一般为65537(0x10001),假如后两个参数不为NULL,将有些调用。在产生密钥对之前,一般需要指定随机数种子
 
4、判断位数函数
  int RSA_size(const RSA *rsa);返回RSA模的位数,他用来判断需要给加密值分配空间的大小
 
5、加解密函数
1)公钥加密函数
int RSA_public_encrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa, int padding);
 
2)私钥解密函数
int RSA_private_decrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa, int padding);
3)私钥加密函数
int RSA_private_encrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa,int padding);
4)公钥解密函数
int RSA_public_decrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa,int padding);
flen为要加/解密信息的长度,from为需要加/解密的信息,to为加/解密后的信息,一般to至少要申请 BN_num_bytes(rsa->n)大的空间。加密时Padding表示填充方式,解密时表示去填充方式。

6、 释放函数
void RSA_free(RSA *rsa);释放一个RSA结构
 
7、与字符串处理相关函数
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);将s中的len位的正整数转化为大数
 
三、代码示例
1、公钥加密

void CPage4::OnButtonPubDecrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();

 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);
 
 inputlen=RSA_size(pRsa);

 int ret = RSA_public_encrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("公钥加密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }

 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);
}

 
2、私钥解密

void CPage4::OnButtonPriDecrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();
 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);

 //inputlen=RSA_size(pRsa)-11;

 int ret = RSA_private_decrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("私钥解密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }

 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);
}

 
3、私钥加密

void CPage4::OnButtonEncrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();
 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);

 inputlen=RSA_size(pRsa);

 int ret = RSA_private_encrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("私钥加密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }
 
 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);

}

 

4、公钥解密

void CPage4::OnButtonDecrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();
 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);

 //inputlen=RSA_size(pRsa)-11;

 int ret = RSA_public_decrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("公钥解密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }

 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);
}

 

5、产生RSA密钥对

void CPage4::OnButtonRsa()
{
 // TODO: Add your control notification handler code here
 RSA* key;
 unsigned char rsa_n[1024];
 unsigned char rsa_d[1024];
 char keylen[10];
 int len;

 UpdateData(TRUE);

 strcpy(keylen,m_keylen);
 len = atoi(keylen);

 key = RSA_new();

 key = RSA_generate_key(len,0x10001,NULL,NULL);

 BN_bn2bin(key->n,rsa_n ); // 保存公钥
 BN_bn2bin(key->d,rsa_d ); // 保存私钥

 RSA_free(key);

 HexToStr(rsa_n,len/8,m_publickey_n);
 HexToStr(rsa_d,len/8,m_privatekey_d);

 UpdateData(FALSE);

}

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OPENSSL库的使用-RSA篇 的相关文章

随机推荐

  • java模拟post请求发送json数据

    import com alibaba fastjson JSONObject import org apache http client methods CloseableHttpResponse import org apache htt
  • Python3中pickle模块介绍

    Pyhton3中的pickle模块用于对Python对象结构的二进制进行序列化 或pickling 和反序列化 或unpickling pickling 是将Python对象及其所拥有的层次结构转化为一个字节流 byte stream 的过
  • 首次使用计算机 鼠标没反应,鼠标没反应各种解决方法教程

    我们在使用鼠标的时候开始肯定没问题 但长期使用下来 总会出现一种故障 比如最常见的鼠标没反应的问题 也就是说不管你怎么滑动鼠标 显示器里的光标都不动了 这种问题怎么解决呢 我们要分成有线鼠标和无线鼠标两种情况 一 有线鼠标没反应 一般有线鼠
  • kalilinux搭建DCN漏洞靶场

    kalilinux系统搭建DCN漏洞靶场 前言 安装kalilinux 搭建靶场 WinSCP连接kalilinux实现文件上传 导入镜像 前言 最近想学一下WEB安全 顺便学习一下靶场环境的搭建 之前搭建过webug玩了一下 但自己电脑运
  • 编程的美学标准诌议

    编程的美学标准诌议 做了几年的程序员 虽然自己写的代码还远远没有达到要求 但在日复一日的实践过程中 我逐渐开始信奉一条标准 在实现功能的前提下 简单即是美 其实 编程的过程就好比是一个建模的过程 设计就是将一个现实问题抽象成逻辑模型 而编码
  • git命令使用上传下载详情大全...

    不罗嗦直接上内容 git branch 查看本地所有分支 git status 查看当前状态 git commit 提交 git branch a 查看所有的分支 git branch r 查看远程所有分支 git commit am in
  • CISCN(Web Ezpentest)GC、序列化、case when

    目录 REGEXP的一个点 正则 like 默认不区分大小写 当禁用了空格 regexp like的区分大小写的使用方法 CISCN 2022 初赛 ezpentest 卡点 2022 HFCTF babysql 最近又学到了一道新知识 c
  • attrs.xml中declare-styleable 详解(用于自定义控件的属性)

    1 框架定义
  • simulink电力电子仿真(3)单相桥式全控整流电路

    simulink电力电子仿真 3 单相桥式全控整流及有源逆变电路 返回目录 主要是赶上了疫情 然后期末要疯狂补实验报告 就索性写一下吧 万一以后再做电力电路仿真 可能会有用的 也希望可以帮助别人 器件的选择及位置 MATLAB的版本 201
  • 【k8s集群管理工具篇】云原生之部署K8s管理面板KubePi

    k8s集群管理工具篇 云原生之部署K8s管理面板KubePi 一 KubePi介绍 二 环境规划 三 检查本地环境 1 检查k8s集群状态 2 检查kubepi管理主机环境 三 部署KubePi 1 创建KubePi容器 2 检查KubeP
  • Flutter填坑 编译运行不起来

    记录下Flutter中遇到的一些问题 基本上按照Flutter中文网的教程可以完成Flutter环境的搭建 Flutter中文网 https flutterchina club Windows 环境 https flutterchina c
  • sqli-labs 靶场环境搭建

    目录 一 搭建环境所需资源 搭建sqli labs 靶场需要的运行环境 二 搭建过程 1 下载资源 2 创建网站 3 更改配置文件 4 安装数据库 不使用 php7 x 版本的原因 一 搭建环境所需资源 搭建sqli labs 靶场需要的运
  • 21计算机考研国家线,来了!21考研国家线公布!附详细解读!

    原标题 来了 21考研国家线公布 附详细解读 21考研人最近大概都在焦虑的等待国家线 昨天中国农业大学的一条消息直接将 考研国家线 顶上热搜 这不 最新出炉的国家线就来了 21考研国家线公布 21国家线学硕总分线上涨的门类有 经济学 历史学
  • 人工智能还是人工智障

    序言 有的时候感觉有脑子 有的时候感觉没有 到底是有还是没有呢 机器人 有的很智能 有的很智障 是智能的时候可爱 还是在智障的时候可爱 你是惧怕智障还是惧怕人工智能 风言风语 作为一个吵架之王 每次吵架的时候都会想 现在人工智能这么多 但是
  • 【支持向量机】最大间隔超平面及Matlab代码

    线性可分 在特征空间中 有两个训练样本可以通过一条直线区分开 则称为线性可分 而在特征空间大于等于四维时 分开训练样本的平面 称为超平面 我们定义一条直线方程 1 x 1
  • Linux 之exit() 进程退出函数

    进程的退出 linux下进程数量太多会导致系统崩溃 在使用完一个进程之后要及时终止它 进程退出一般有三种方法 1 在main函数中使用 return关键字 使用 return 后系统会调用 exit 函数来终止进程 2 手动调用 exit
  • C++ 关于 protobuf的一些操作

    先是定义部分 下面跟一些例子组成 message DBRoleData uint64 RoleID 2 string Name 6 repeated int64 Action 12 存内置重复单位 message DBRoleLoginAc
  • Kylin 10 SP1(UI)磁盘自行配置lvm

    1 登录服务器 输入 lsblk 查看新磁盘名称 我以sdb为例 sdb1是我为其建立的分区 2 新建分区 fidsk dev sdb 先输入n 新建分区 然后输入p 建立分区 其余选项默认 最后一步输入w保存 3 格式化分区 mkfs x
  • strapi的使用(二)-- Graphql

    一 Graphql 一种为你的API而生的查询语言 可以理解为动态api 一般来说我们都是在后端写好sql查询语句查询数据库数据 前端请求这个api返回的数据是固定的 而Graphql可以让前端去决定请求什么字段回来 二 strapi安装G
  • OPENSSL库的使用-RSA篇

    一 RSA算法简介 RSA公钥加密算法是1977年由Ron Rivest Adi Shamirh和LenAdleman在 美国麻省理工学院 开发的 RSA取名来自开发他们三者的名字 RSA是目前最有影响力的公钥加密算法 它能够抵抗到目前为止