公钥密码体制即公开密钥密码体制,也称非对称密码体制或双密钥密码体制。1978年由美国麻省理工学院的Rivest、Shamir和Adleman共同提出了第一个有效的公钥密码体制——RSA公钥密码体制,目前RSA仍然应用于网络银行、电子贸易等许多电子商务领域。

一、RSA公钥密码体制原理

1. 参数定义与密钥生成

(1)用户首先秘密选择两个大素数p,q,然后计算出N=pq。

(2)用户计算出p-1和q-1的最小公倍数n,然后随机选择一个整数e,满足1<e<n,且e和n互素,将其作为加密密钥,有时也称e为加密指数。

(3)然后用户利用加密密钥e和n可容易地计算出脱密密钥d,使得:ed (mod n)=1,有时也称d为脱密指数。

(4)用户将加密密钥及大合数(e,N)公布为其公开参数,而将两个大素数p,q及脱密密钥d严格保密作为秘密参数。

2. 加密、解密公式

设明文为m,密文为c,E表示加密算法,D表示脱密算法,于是有:

加密:c=E(m)=m^e(mod N)

解密:m=D(c)=c^d(mod N)

二、C++代码实现

BigInt.h

#ifndef BIGINT_H_INCLUDED
#define BIGINT_H_INCLUDED
#include <iostream>
#include <string>
#include <cstdlib>
#include <algorithm>//reverse函数所需添加的头文件
using namespace std;
/*
大整数类
*/
class BigInt
{
private:inline int compare(string s1, string s2){if(s1.size() < s2.size())return -1;else if(s1.size() > s2.size())return 1;elsereturn s1.compare(s2);}
public:bool flag;//true表示正数,false表示负数,0默认为正数string values;//保存所有位上的数字BigInt():values("0"),flag(true){};//构造函数BigInt(string str)//类型转换构造函数(默认为正整数){values = str;flag = true;}
public:friend ostream& operator << (ostream& os, const BigInt& bigInt);//重载输出操作符friend istream& operator>>(istream& is, BigInt& bigInt);//输入操作符重载BigInt operator+(const BigInt& rhs);//加法操作重载BigInt operator-(const BigInt& rhs);//减法操作重载BigInt operator*(const BigInt& rhs);//乘法操作重载BigInt operator/(const BigInt& rhs);//除法操作重载BigInt operator%(const BigInt& rhs);//求余操作重载
};
/*
重载流提取运算符'>>',输出一个整数
*/
ostream& operator << (ostream& os, const BigInt& bigInt)
{if (!bigInt.flag){os << '-';}os << bigInt.values;return os;
}
/*
重载流插入运算符'>>',输入一个正整数
*/
istream& operator >> (istream& is, BigInt& bigInt)
{string str;is >> str;bigInt.values = str;bigInt.flag = true;return is;
}
/*
两个正整数相加
*/
BigInt BigInt::operator+(const BigInt& rhs)
{BigInt ret;ret.flag = true;//正整数相加恒为正数string lvalues(values), rvalues(rhs.values);//处理特殊情况if (lvalues == "0"){ret.values = rvalues;return ret;}if (rvalues == "0"){ret.values = lvalues;return ret;}//调整s1与s2的长度unsigned int i, lsize, rsize;lsize = lvalues.size();rsize = rvalues.size();if (lsize < rsize){for (i = 0; i < rsize - lsize; i++)//在lvalues左边补零{lvalues = "0" + lvalues;}}else{for (i = 0; i < lsize - rsize; i++)//在rvalues左边补零{rvalues = "0" + rvalues;}}//处理本质情况int n1, n2;n2 = 0;lsize = lvalues.size();string res = "";reverse(lvalues.begin(), lvalues.end());//颠倒字符串,以方便从低位算起计算reverse(rvalues.begin(), rvalues.end());for (i = 0; i < lsize; i++){n1 = (lvalues[i] - '0' + rvalues[i] - '0' + n2) % 10;//n1代表当前位的值n2 = (lvalues[i] - '0' + rvalues[i] - '0' + n2) / 10;//n2代表进位res = res + char(n1 + '0');}if (n2 == 1){res = res + "1";}reverse(res.begin(), res.end());ret.values = res;return ret;
}
/*
两个整数相减
*/
BigInt BigInt::operator-(const BigInt& rhs)
{BigInt ret;string lvalues(values), rvalues(rhs.values);//负数减负数if(flag==false&&rhs.flag==false){string tmp = lvalues;lvalues = rvalues;rvalues = tmp;}//负数减正数if(flag==false&&rhs.flag==true){BigInt res(lvalues);ret=res+rhs;ret.flag = false;return ret;}if(flag==true&&rhs.flag==false){BigInt rel(lvalues),res(rhs.values);ret=rel+res;ret.flag = true;return ret;}//处理特殊情况if (rvalues == "0"){ret.values = lvalues;ret.flag = true;return ret;}if (lvalues == "0"){ret.values = rvalues;ret.flag = false;return ret;}//调整s1与s2的长度unsigned int i, lsize, rsize;lsize = lvalues.size();rsize = rvalues.size();if (lsize < rsize){for (i = 0; i < rsize - lsize; i++)//在lvalues左边补零{lvalues = "0" + lvalues;}}else{for (i = 0; i < lsize - rsize; i++)//在rvalues左边补零{rvalues = "0" + rvalues;}}//调整使‘-’号前边的数大于后边的数int t = lvalues.compare(rvalues);//相等返回0,str1<str2返回负数,str1>str2返回正数if (t < 0){ret.flag = false;string tmp = lvalues;lvalues = rvalues;rvalues = tmp;}else if (t == 0){ret.values = "0";ret.flag = true;return ret;}else{ret.flag = true;}//处理本质情况unsigned int j;lsize = lvalues.size();string res = "";reverse(lvalues.begin(), lvalues.end());//颠倒字符串,以方便从低位算起计算reverse(rvalues.begin(), rvalues.end());for (i = 0; i < lsize; i++){if (lvalues[i] < rvalues[i])//不足,向前借一维{j = 1;while(lvalues[i+j] == '0'){lvalues[i+j] = '9';j++;}lvalues[i+j] -= 1;res = res + char(lvalues[i] + ':' - rvalues[i]);}else{res = res + char(lvalues[i] - rvalues[i] + '0');}}reverse(res.begin(), res.end());res.erase(0, res.find_first_not_of('0'));//去掉前导零ret.values = res;return ret;
}/*
两个整数相乘
*/
BigInt BigInt::operator*(const BigInt& rhs)
{BigInt ret;string lvalues(values), rvalues(rhs.values);//处理0或结果正负if (lvalues == "0" || rvalues == "0"){ret.values = "0";ret.flag = true;return ret;}if(flag==false||rhs.flag==false){ret.flag=false;}//处理特殊情况unsigned int lsize, rsize;lsize = lvalues.size();rsize = rvalues.size();string temp;BigInt res, itemp;//让lvalues的长度最长if (lvalues < rvalues){temp = lvalues;lvalues = rvalues;rvalues = temp;lsize = lvalues.size();rsize = rvalues.size();}//处理本质情况int i, j, n1, n2, n3, t;reverse(lvalues.begin(), lvalues.end());//颠倒字符串reverse(rvalues.begin(), rvalues.end());for (i = 0; i < rsize; i++){temp = "";n1 = n2 = n3 = 0;for (j = 0; j < i; j++){temp = temp + "0";}n3 = rvalues[i] - '0';for (j = 0; j < lsize; j++){t = (n3*(lvalues[j] - '0') + n2);n1 = t % 10;//n1记录当前位置的值n2 = t / 10;//n2记录进位的值temp = temp + char(n1 + '0');}if (n2){temp = temp + char(n2 + '0');}reverse(temp.begin(), temp.end());itemp.values = temp;res = res + itemp;}ret.values = res.values;return ret;
}
/*
两个正整数相除
*/
BigInt BigInt::operator/(const BigInt& rhs)
{BigInt ret;string lvalues(values), rvalues(rhs.values);string quotient;string temp;//处理特殊情况if(rvalues == "0"){ret.values = "error";//输出错误ret.flag = true;return ret;}if(lvalues == "0"){ret.values = "0";ret.flag = true;return ret;}if(compare(lvalues, rvalues) < 0){ret.values = "0";ret.flag = true;return ret;}else if(compare(lvalues, rvalues) == 0){ret.values = "1";ret.flag = true;return ret;}else{//处理本质情况unsigned int lsize, rsize;lsize = lvalues.size();rsize = rvalues.size();int i;if(rsize > 1) temp.append(lvalues, 0, rsize-1);for(i = rsize - 1; i < lsize; i++){temp = temp + lvalues[i];//试商for(char c = '9'; c >= '0'; c--){BigInt t = (BigInt)rvalues * (BigInt)string(1, c);BigInt s = (BigInt)temp - t;if(s.flag == true){temp = s.values;quotient = quotient + c;break;}}}}//去除前导零quotient.erase(0, quotient.find_first_not_of('0'));ret.values = quotient;ret.flag = true;return ret;
}
/*
两个正整数取余
*/
BigInt BigInt::operator%(const BigInt& rhs)
{BigInt ret,kj(values),ki(rhs.values);string lvalues(values), rvalues(rhs.values);string quotient;string temp;//处理特殊情况if(rvalues == "0"){ret.values = "error";//输出错误ret.flag = true;return ret;}if(lvalues == "0"){ret.values = "0";ret.flag = true;return ret;}if(compare(lvalues, rvalues) < 0){if(flag==false){ret.values=(ki-kj).values;ret.flag = true;return ret;}else{ret.values = lvalues;ret.flag = true;return ret;}}else if(compare(lvalues, rvalues) == 0){ret.values = "0";ret.flag = true;return ret;}else{//处理本质情况unsigned int lsize, rsize;lsize = lvalues.size();rsize = rvalues.size();int i;if(rsize > 1) temp.append(lvalues, 0, rsize-1);for(i = rsize - 1; i < lsize; i++){if(temp=="0"){temp=lvalues[i];}else{temp = temp + lvalues[i];}//试商for(char c = '9'; c >= '0'; c--){BigInt t = (BigInt)rvalues * (BigInt)string(1, c);BigInt s = (BigInt)temp - t;if(s.flag == true){//cout<<s.values<<endl;temp = s.values;quotient = quotient + c;break;}}}}//去除前导零quotient.erase(0, quotient.find_first_not_of('0'));ret.values = temp;ret.flag = true;return ret;
}
/*
一个大整数和一个小整数的取余int divMod(string ch,int num)
{int s=0;for(int i=0;ch[i]!='\0';i++)s=(s*10+ch[i]-'0')%num;return s;
}*//*
欧几里德求GCD
*/
BigInt gcd(BigInt a,BigInt b)
{BigInt stemp;//cout<<a<<endl;//cout<<b<<endl;if((a-b).flag==false)//判断大小{stemp.values=a.values;a.values=b.values;b.values=stemp.values;}if(b.values=="0") return a;else return gcd(b,a%b);
}
/*
快速幂
*/
BigInt fast(BigInt a,BigInt b)
{BigInt aa=a,t("1"),k("2");//   int b2=atoi(b1[lsize-1].c_str());while(b.values!="0"){if((b%k).values!="0"){t=t*aa;}aa=aa*aa;b=b/k;}return t;
}
/*
快速幂模
*/
BigInt mod_fast(BigInt a,BigInt b,BigInt p)
{BigInt aa=a,t("1"),k("2");//   int b2=atoi(b1[lsize-1].c_str());while(b.values!="0"){if((b%k).values!="0"){t=(t%p)*(aa%p)%p;}aa=(aa%p)*(aa%p)%p;b=b/k;}return t%p;
}/*
扩展欧几里德实现乘法逆
*/
BigInt extgcd(BigInt a, BigInt b, BigInt& x, BigInt& y)
{BigInt d(a.values);if(b.values != "0"){d = extgcd(b, a % b, y, x);y = y-(a / b) * x;//   cout<<"a:"<<a<<endl;//  cout<<"b:"<<b<<endl;//  cout<<"x:"<<x<<endl;//  cout<<"y:"<<y<<endl<<endl<<endl;}else {x.values = "1";y.values = "0";}return d;
}
BigInt mod_inverse(BigInt a, BigInt m)
{BigInt x, y;extgcd(a, m, x, y);if(x.flag==false){x.flag=true;x=m-x;}return (m + x % m) % m;
}#endif // BIGINT_H_INCLUDED

main.cpp

#include"BigInt.h"
int main()
{BigInt p("965020263285415169225506842409"),q("415924872698612520126277439911"),N,n,a("1"),b("2");BigInt d,e;BigInt m,s;N=p*q;s=gcd(p-a,q-a);n=s*((p-a)/s)*((q-a)/s);//cout<<s<<endl;//cout<<(p-a)*(q-a)<<endl;cout<<"n: "<<n<<endl;cout<<"N: "<<N<<endl;while(1){cout<<"请输入整数e:"<<endl;cin>>e;cout<<"gcd(e,n): "<<gcd(e,n)<<endl;if(gcd(e,n).values=="1"&&(n-e).flag==true){d=mod_inverse(e,n);cout<<"d:"<<d<<endl;cout<<"请输入需要加密的字符:"<<endl;cin>>m;BigInt t;cout<<"加密:"<<mod_fast(m,e,N)<<endl;cout<<"解密:"<<mod_fast(mod_fast(m,e,N),d,N)<<endl;}else{cout<<"d和N非互素或者非1<e<n!"<<endl;}}return 0;
}

运行结果

RSA公钥密码体制及C++代码实现相关推荐

  1. 【密码学】RSA公钥密码体制

    RSA公钥密码体制是美国麻省理工学院(MIT)的三位科学家Rivest.Shamir.Adleman于1978年提出的,简称RSA公钥秘密系统.实际上,RSA稍后于MH背包公钥密码实用系统,但它的影响 ...

  2. RSA公钥密码体制的简介及例题

    目录 传统密码体制 传统的对称密码体制 密钥管理 密钥分发 不支持"开放系统" 公钥密码体制 主要思想: 公钥密码体制的优势: 密钥分发: 密钥管理: 开放系统: 算法原理 练习 ...

  3. 使用OpenSSL加密,使用Java解密,使​​用OpenSSL RSA公钥

    抽象 在2017年,我撰写了一个由三部分组成的系列文章,内容涉及选择最佳的哈希和加密算法. 在对该系列进行研究时,我学到了很多有关哈希和加密的知识. 我学到的最重要的事情是,尽管我必须对如何使用最安全 ...

  4. 第五章 公钥密码体制

    目录 5.1 公钥密码体制 5.1.1 概述 5.1.2 单向函数和陷门函数 5.1.2 D-H密钥交换协议 5.1.3 中间人攻击 5.2 RSA公钥密码体制 5.2.1 RSA公钥密码体制及其工作 ...

  5. 密码学系列之六:公钥密码体制

    公钥密码体制 1. 概述 1.1 公钥密码体制的提出 1.2 公钥密码体制的原理 1.3 常见公钥密码体制 2. RSA公钥密码 2.1 RSA密码体制 2.2 RSA公钥密码安全性 3. ElGam ...

  6. 公钥密码体制(RSA,椭圆曲线密码,ElGamal

    目录 概述 RSA 密钥的产生 加密: 解密: ElGamal: 椭圆密码曲线密码ECC: 概述 密钥是需要定期更换的.如果采用对称密钥体制(分组密码和序列密码)更换密钥以及相应的"密钥分发 ...

  7. 公钥密码体制之RSA

    记一次密码学上课所学的公钥密码体制学习.从一开始的古典密码到流密码再是分组密码,再是现在的公钥密码体制. 产生原因 公钥密码体制的产生主要是因为两个方面的原因:一是由于常规的密钥密码体制的密钥分配问题 ...

  8. 10行代码实现RSA公钥解密

    RSA常用场景是: 1)生成公钥.私钥 2)公钥加密,私钥解密 3)私钥签名,公钥验签(返回成功or失败) 以上场景实现比较简单,网上大把的文章,大部分加密库也都支持,我不再赘述. 如果你遇到稀有场景 ...

  9. merkle-hellman背包算法 java_浅析几种公钥密码体制-RSA;Merkle-Hellman、背包加密体制、ECC优缺点...

    自从公钥密码体制被提出以来,出现了许多公钥密码方案 如RSA.ELGamal密码体制.背包算法和ECC.XTR.NTRU等. 下面就介绍一下各种密码体制的优缺点,并进行比较. 2RSA 在Diffie ...

最新文章

  1. Linux TCP/IP协议栈笔记
  2. 清理mysql创建的游戏_Linux定时清理游戏log及mysql定时任务删除游戏日志数据的步骤...
  3. (视频) 基于HTML5的服务器远程访问工具
  4. 切换卡TabHost控件的使用
  5. 七自由度车辆稳定性数学模型和simulink求解
  6. 排序算法java 简书_史上最全经典排序算法总结(Java实现)
  7. fitbit手表中文说明书_如何获取和分析Fitbit睡眠分数
  8. NoPause/NoEmgAbort的任务 与后台任务的区别
  9. funuiTitle-居中问题修改
  10. Windows 10 超过Windows 7成为最受欢迎的操作系统
  11. 小学计算机学什么,小学信息技术课学什么
  12. 群智能算法(遗传算法, 粒子群算法, 蚁群算法原理与实例分析)
  13. 共识,权威以及去中心化的区块链
  14. 人脸特征点定位方法DEST, 基于VS2019+OpenCV3.4.6
  15. 经营养生理疗馆要注意什么问题?
  16. MT4-EA自动化交易研究笔记(2022-05-15)
  17. 禅道 upgrade.php,zentao禅道安装升级
  18. 后端要学MySQL_做后端开发需要学什么
  19. 紫薇星上的Java——映射转换
  20. onvif 客服端鉴权

热门文章

  1. svn服务器如何删文件,windows下 svn服务器端 无法删除文件,只能删除文件夹,这是怎么回...
  2. 计算机办公软件知识考试试题,office办公软件考试题「附答案」
  3. Supermarket | 贪心
  4. react路由跳转传参
  5. oracle常用函数小结(三)
  6. 互联网舆情与评论数据信息怎么检索的方法技巧
  7. cocos2d-x游戏《StopGMO》现阶段成品及代码发布
  8. Protege初学者
  9. 聊聊旷厂黑科技 | 屏下指纹识别,方寸间的谷脊之战
  10. 亚马逊、阿里国际、Shopee、Temu等跨境电商平台测评自养号经验分享