RSA.h
#ifndef _RSA_H
#define _RSA_H
#include<stdio.h>
#include<iostream>
#include<math.h>
/*
密钥产生:
1.随机选定两个大素数p, q.
2.计算公钥和私钥的公共模数 n = pq .
3.计算模数n的欧拉函数 φ(n) .
4.选定一个正整数e, 使1 < e < φ(n) , 且e与φ(n)互质.
5.计算d, 满足 de ≡ 1 (mod φ(n) ), (k为某个正整数).
6.n与e决定公钥, n与d决定私钥.
*/
/*
加密:C=M^e mod n
*/
/*
解密:C=M^d mod n
*/
//#define RAND_MAX_64 9223372036854775807//最大素数2^63-1
//#define RAND_MIN_64 2147483647//最小素数2^31-1
#define RAND_MAX_64 1000000
#define RAND_MIN_64 1000
#define Max_64 9223372036854775807
#define Times 10//测试素数次数 class RSA
{
public:
RSA();
~RSA(void);
void encryption(__int64 *M,__int64 *C);
void decryption(__int64 *C,__int64 *M);
void getKey();//生成密钥
__int64 get_p(){return p;};
__int64 get_q(){return q;};
__int64 get_n(){return n;};
__int64 get_o(){return o;};
__int64 get_e(){return e;};
__int64 get_d(){return d;};
private:
__int64 Sqrt(__int64 num); //大数开平方根
__int64 get_Prime(); //得到大素数
__int64 mod(__int64 a,__int64 m,__int64 n);//快速求模
__int64 Euclid(__int64 a,__int64 b); //欧几里德算法
bool Prime_test(__int64 n); //确定性测试
bool Witness(__int64 a,__int64 n); //概率测试
bool Extended_Euclid(__int64 a,__int64 n,__int64 *d); //扩展的欧几里德算法
//公钥KU={e,n}
//私钥KR={d,p,q}/{d,n}
__int64 p;//素数p
__int64 q;//素数q
__int64 n;//n=p*q
__int64 o;//φ(n)=(p-1)(q-1)
__int64 e;//随机整数
__int64 d;//d=e^-1
};
#endif
RSA.cpp
#include"RSA.h"
//构造函数
RSA::~RSA(){};
//析构函数
RSA::RSA(){};
//加密
void RSA::encryption(__int64 *M,__int64 *C){
*C=RSA::mod(*M,this->e,this->n);
}
//解密
void RSA::decryption(__int64 *C,__int64 *M){
*M=RSA::mod(*C,this->d,this->n);
}
//快速求模
//d=a^m mod n b[k]=m=(101010010)
__int64 RSA::mod(__int64 a,__int64 m,__int64 n){
__int64 b[],k=,i;
__int64 c, d;
for(;m!=;m>>=){
if(m%==)
b[k]=;
else
b[k]=;
k++;
}
c=;
d=;
for(i=k;i>=;i--){
c=*c;
d=(d*d)%n;
if(b[i]==){
c=c+;
d=(d*a)%n;
}
//printf("%lld ",c);
//printf("%lld\n",d);
}
return d;
}
//确定性测试
//n素数
bool RSA::Prime_test(__int64 n){
__int64 r=;
while(r<Sqrt(n)){
if(n%r==)
return false;
r=r+;
}
return true;
}
//概率测试
//n为素数,a<n
bool RSA::Witness(__int64 a,__int64 n){
__int64 m=n-;
__int64 b[],k=,i;
__int64 d,x;
for(;m!=;m>>=){
if(m%==)
b[k]=;
else
b[k]=;
k++;
}
d=;
for(i=k;i>=;i--){
x=d;
d=(d*d)%n;
if(d==&&x!=&&x!=n-)
return true;//合数
if(b[i]==)
d=(d*a)%n;
}
if(d!=)
return true;//合数
return false;//可能是素数
}
//欧几里德算法
__int64 RSA::Euclid(__int64 a,__int64 b){
__int64 x=b,y=a,r=;
if(y>){
r=x%y;
x=y;
y=r;
}
return x;
}
//扩展的欧几里德算法
//d=e^-1 mod n
bool RSA::Extended_Euclid(__int64 a,__int64 n,__int64 *d){
__int64 x1=,x2=,x3;
__int64 y1=,y2=,y3;
__int64 t1,t2,t3,q;
x3=(n>=a)?n:a;//大的数
y3=(n>=a)?a:n;//小的数
while(){
if(y3==){
*d=x3;
return false;
}
if(y3==){
*d=y2;
return true;
}
q=x3/y3;
t1=x1-q*y1;
t2=x2-q*y2;
t3=x3-q*y3;
x1=y1;x2=y2;x3=y3;
y1=t1;y2=t2;y3=t3;
}
}
//得到大素数
__int64 RSA::get_Prime(){
int flag=; //
int times=;//测试素数次数
__int64 a,n=;
while(flag==){
//步骤1
step_1:flag=;
n = (__int64)(rand()%(RAND_MAX_64 - RAND_MIN_64+))+RAND_MIN_64;
n=(n/)*+;
printf("%lld%\r",n);
//步骤2
if(Prime_test(n)==false){
//返回步骤1
goto step_1;
}
else{
//步骤3
step_3:a = (__int64)(rand()%(n--+))+;//0<a<n
//步骤4
if(Witness(a,n)==true){
//返回步骤1
goto step_1;
}
else{
times++;
if(times>=Times){
flag=;
return n;
}
else{
//返回步骤3
goto step_3;
}
}
}
}
return ;
}
//密钥的生成
void RSA::getKey(){
this->p = get_Prime();
this->q = get_Prime();
this->n = this->p*this->q;//n=p*q
this->o = (this->p-)*(this->q-);//φ(n)=(p-1)(q-1)
do{
this->e = (__int64)(rand()%(this->o+));//0<e<φ(n)
}while(==Euclid(this->e,this->o));//e与φ(n)互质
//this->e = 3;
if(true==Extended_Euclid(this->e,this->o,&(this->d))){
while(this->d<=Sqrt(Sqrt(this->n))){
Extended_Euclid(this->e,this->o,&(this->d));
}
printf("密钥生成成功:%lld\n",this->d);
}
else{
RSA::getKey();
}
}
//大数开根
__int64 RSA::Sqrt(__int64 num){
__int64 low ,mid ,up;
low = ,up = num;
if(up > Max_64) up = Max_64;
__int64 mk = ;
while(low <= up){
mid = (low + up) / ;
if(mid * mid > num){
up = mid - ;
}
else{
low = mid + ;
mk = mid;
}
}
return mk;
}
TEST.cpp
#include"RSA.h"
#include<stdio.h> int main(){
__int64 M=,C=;
RSA rsa = RSA();
printf("----------生成密钥----------\n");
rsa.getKey();
printf("----------输出密钥----------\n");
printf("p:%lld\n",rsa.get_p());
printf("q:%lld\n",rsa.get_q());
printf("n:%lld\n",rsa.get_n());
printf("o:%lld\n",rsa.get_o());
printf("e:%lld\n",rsa.get_e());
printf("d:%lld\n",rsa.get_d());
printf("----------加密信息----------\n");
printf("请输入明文:\n");
scanf("%lld",&M);
rsa.encryption(&M,&C);
printf("加密后密文:%lld\n",C);
printf("----------解密信息----------\n");
printf("请输入密文:\n");
scanf("%lld",&C);
rsa.decryption(&C,&M);
printf("解密后明文:%lld\n",M); system("pause");
return ;
}

RSA算法的更多相关文章

  1. 信息安全-5:RSA算法详解(已编程实现)[原创]

    转发注明出处:http://www.cnblogs.com/0zcl/p/6120389.html 背景介绍 1976年以前,所有的加密方法都是同一种模式: (1)甲方选择某一种加密规则,对信息进行加 ...

  2. RSA算法原理

    一直以来对linux中的ssh认证.SSL.TLS这些安全认证似懂非懂的.看到阮一峰博客中对RSA算法的原理做了非常详细的解释,看完之后茅塞顿开,关于RSA的相关文章如下 RSA算法原理(一) RSA ...

  3. C#RSA算法实现+如何将公钥为XML格式转为PEM格式,给object-C使用

    .net中,处于安全的考虑,RSACryptoServiceProvider类,解密时只有同时拥有公钥和私钥才可以.原因是公钥是公开的,会被多人持有.这样的数据传输是不安全的.C#RSA私钥加密,公钥 ...

  4. [已解决] 快速理解RSA算法

    RSA算法基础详解 http://www.cnblogs.com/hykun/p/RSA.html RSA算法原理(一) http://www.ruanyifeng.com/blog/2013/06/ ...

  5. 公钥私钥和RSA算法

    1, RSA算法原理(一) http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html 2, RSA算法原理(二) http: ...

  6. 跨越千年的RSA算法

    转载自http://www.matrix67.com/blog/archives/5100 数论,数学中的皇冠,最纯粹的数学.早在古希腊时代,人们就开始痴迷地研究数字,沉浸于这个几乎没有任何实用价值的 ...

  7. (转)RSA算法原理(二)

      作者: 阮一峰 日期: 2013年7月 4日 上一次,我介绍了一些数论知识. 有了这些知识,我们就可以看懂RSA算法.这是目前地球上最重要的加密算法. 六.密钥生成的步骤 我们通过一个例子,来理解 ...

  8. (转) RSA算法原理(一)

    最近用到了RSA加密算法,虽然有现成的,但是想看看它的原理,翻到此文,感觉写得很好,通俗易懂,转了.   作者: 阮一峰 日期: 2013年6月27日 如果你问我,哪一种算法最重要? 我可能会回答&q ...

  9. springmvc使用RSA算法加密表单

    今天被吐槽在客户端用js对密码进行md5加密其实也不见得安全.这种做法其实不见得有什么作用,学过计算机网络都知道,在网上抓一个包是很简单的事,就算别人抓包抓不到你原始密码,用这个md5后的密码一样可以 ...

  10. RSA算法基础详解

    . 首页 博客园 联系我 前言:在RSA诞生之前. RSA算法. 质数与互质数. 模运算. 同余. 欧拉函数. 欧拉定理与模反元素. 真实的例子. 计算密钥. 密钥组成与加解密公式. 安全性. 一点感 ...

随机推荐

  1. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  2. C++内存对齐总结

    大家都知道,C++空类的内存大小为1字节,为了保证其对象拥有彼此独立的内存地址.非空类的大小与类中非静态成员变量和虚函数表的多少有关. 而值得注意的是,类中非静态成员变量的大小与编译器内存对齐的设置有 ...

  3. 0-1背包问题蛮力法求解(c++版本)

    // 0.1背包求解.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream>   #define ...

  4. Unity游戏内版本更新

    最近研究了一下游戏内apk包更新的方法. ios对于应用的管理比较严格,除非热更新脚本,不太可能做到端内大版本包的更新.然而安卓端则没有此限制.因此可以做到不跳到网页或应用商店,就覆盖更新apk包. ...

  5. java head space/ java.lang.OutOfMemoryError: Java heap space内存溢出

    上一篇JMX/JConsole调试本地还可以在centos6.5 服务器上进行监控有个问题端口只开放22那么设置的9998端口 你怎么都连不上怎么监控?(如果大神知道还望指点,个人见解) 线上项目出现 ...

  6. 再谈C#采集,一个绕过高强度安全验证的采集方案?方案很Low,慎入

    说起采集,其实我是个外行,以前拔过阿里巴巴的客户数据,在我博客的文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子) 中,介绍过采集用的工具,其实很Low的,分析 ...

  7. [.NET] 利用 async & await 的异步编程

    利用 async & await 的异步编程 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/5922573.html  目录 异步编程的简介 异 ...

  8. ASP.NET MVC开发日常一:SessionID合理清除

    在MVC Web开发中临时存储数据一般会用到Session,Cookie,ViewBag,ViewData,TempData.每个的使用场景是不同,具体区别有空再补上. Session数据最敏感,最需 ...

  9. Android之网络数据存储

    一.网络保存数据介绍 可以使用网络来保存数据,在需要的时候从网络上获取数据,进而显示在App中. 用网络保存数据的方法有很多种,对于不同的网络数据采用不同的上传与获取方法. 本文利用LeanCloud ...

  10. [原创]ubuntu16.04LTS使用细节

    如何给自己安装的应用创建桌面图标 拿php开发神器phpstorm为例,找到可执行文件所在路径. 这里是/home/haive/PhpStorm/bin/phpstorm.sh 打开dash,搜索&q ...