在线rsa加密解密 rsa加密解密原理及流程
Android使用RSA加密和解密
if(argv[1][0]!='-')1.data是要加密的数据,如果是字符串则getBytes。publicKey是公钥,privateKey是私钥。自定义密钥对测试
在线rsa加密解密 rsa加密解密原理及流程
在线rsa加密解密 rsa加密解密原理及流程
在线rsa加密解密 rsa加密解密原理及流程
2.从文件中读取公钥
当加密的数据过长时,会出现jax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes的异常。rsa算法规定一次加密的数据不能超过生成密钥对时的keyLength/8-11,keyLength一般是1024个字节,则加密的数据不能超过117个字节
测试分RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法)。段加密和解密
生成公钥和私钥后,用base64编码
一、android加密的数据上无法解密?
android的rsa加密方式是RSA/ECB/NoPadding,而标准jdk是RSA/ECB/PKCS1Padding,所以加密时要设置标准jdk的加密方式
二、base64编码。因为不同的设备对字符的处理方式不同,字符有可能处理出错,不利于传输。所以先把数据做base64编码,变成可见字符,减少出错
提供的base64类,Base64.encode编码,Base64.decode解码。用这个会有换行符,需要自定义
三、rsa是非对称加密算法。依赖于大数计算,加密速度比des慢,通常只用于加密少量数据或密钥
四、公钥加密比私钥加密块,公钥解密比私钥解密慢。加密后的数据大概是加密前的1.5倍
rsa算法中p,q,n,e,d一般大小都为多少啊?
系统的太慢,用了别人的RSA遭受攻击的很多情况是因为算法实现的一些细节上的漏洞所导致的,所以在使用RSA算法构造密码系统时,为保证安全,在生成大素数的基础上,还必须认真仔细选择参数,防止漏洞的形成。根据RSA加解密过程,其主要参数有三个:模数N,加密密钥e,解密密钥d。
3.4.1 模数N的确定
虽然迄今人们无法证明,RSA系统等于对N因子分解,但一般相信RSA系统的安全性等同于因子分解,即:若能分解因子N,即能攻破RSA系统,若能攻破RSA系统,即能分解因子Ⅳ。因此,在使用RSA系统时,对于模数N的选择非常重要。在RSA算法中,通过产生的两个大素数p和q相乘得到模数N,而后分别通过对它们的数算得到密钥对。由此,分解模数N得到p和q是最显然的攻击方法,当然也是最困难的方法,如果模数N被分解,攻击者利用得到的P和q便可计算出,进而通过公开密钥e由解密密钥d,则RSA体制立刻被攻破。相当一部分的对RSA的攻击就是试图分解模数N,选择合适的N是实现RSA算法并防止漏洞的重要环节。一般地,模数N的确定可以遵循以下几个原则:
①p和q之要大。
当p和q相很小时,在已知n的情况下,可定二者的平均值为,然后利用,若等式右边可开方,则得到及,即N被分解。
②p-1和q-1的公因子应很小。
③p和q必须为强素数。
一素数p如果满足:
条件一:存在两个大素数,,使得|p-1且|p+1;
条件二:存在四个大素数,,,使得。则此素数为强素数。其中,,,称为3级的素数,,称为2级的素数,p则称为1级的素数,很明显地,任何素数均为3级的素数。只有两个强素数的积所构成的N,其因子分解才是较难的数学问题。
④p和q应大到使得因子分解N为计算上不可能。
RSA的安全性依赖于大数的因子分解,若能因子分解模数N,则RSA即被攻破,因此模数N必须足够大直至因子分解N在计算上不可行。因子分解问题为密码学最基本的难题之一,如今,因子分解的算法已有长足的进步,但仍不足以说明RSA可。为保证安全性,实际应用中所选择的素数P和拿至少应该为300位以上的二进制数,相应的模数N将是600位以上的二进制数。
目前,SET(Secure Electronic Transaction)协议中要求CA采用2048比特长的密钥,其他实体使用1024比特的密钥。随着计算能力的提高和分布式运算的发展,安全密钥的长度将是动态增长的。
Jadith Moore给出了使用RSA时有关模数的一些限制:
①若给定模数的一个加/解密密钥指数对已知,攻击者就能分解这个模数。
②若给定模数的一个加/解密密钥指数对已知,攻击者无需分解模数Ⅳ就可以计算出别的加/解密密钥指数对。
③在通信网络中,利用RSA的协议不应该使用公共模数。
④消息应该用随机数填充以避免对加密指数的攻击。
3.4.2 e的选取原则
在RSA算法中,e和互质的条件容易满足,如果选择较小的e,则加、解密的速度加快,也便于存储,但会导致安全问题。
一般地,e的选取有如下原则:
①e不能够太小。在RSA系统中,每人的公开密钥P只要满足即可,也即e可以任意选择,为了减少加密运算时间,很多人采用尽可能小的e值,如3。但是已经证明低指数将会导致安全问题,故此,一般选择e为16位的素数,可以有效防止攻击,又有较快速度。
②e应选择使其在的阶为。即存在i,使得,
可以有效抗击攻击。
3.4.3 d的选取原则
一般地,私密密钥d要大于。在许多应用场合,常希望使用位数较短的密钥以降低解密或签名的时间。例如IC卡应用中,IC卡CPU的计算能力远低于计算机主机。长度较短的d可以减少IC卡的解密或签名时间,而让较复杂的加密或验证预算(e长度较长)由快速的计算机主机运行。一个直接的问题就是:解密密钥d的长度减少是否会造成安全性的降低?很明显地,若d的长度太
小,则可以利用已知明文M加密后得,再直接猜测d,求出是否等于M。若是,则猜测J下确,否则继续猜测。若d的长度过小,则猜测的空间变小,猜中的可能性加大,已有证明当时,可以由连分式算法在多项式时间内求出d值。因此其长度不能过小。
#include
#include
#include
#include
#include
int str2num(char str) //字符转数字
{int i=0,num=0;
for(i=0;i<(int)strlen(str);i++)
return num;
}float CarmSqrt(float x) //求平方根 系统的太慢,用了别人的
{union
{int intPart;
float floatPart;
}convertor;
union
{int intPart;
float floatPart;
}convertor2;
convertor.floatPart = x;
convertor2.floatPart = x;
convertor.intPart = 0x1FBCF800 + (convertor.intPart >> 1);
convertor2.intPart = 0x5f3759df - (convertor2.intPart >> 1);
return 0.5f(convertor.floatPart + (x convertor2.floatPart));
}//可以不用,用sqrt()也可以
int isPrime(int n) //判断是否为素数
{int i=0,k=2;
k=(int)CarmSqrt(n);
{if(n%i==0)
break;
}if(i>k)
return 1;
else
return 0;
}int rnd(int max) //生成随机数 2~max 用来生成e,
{ //取系统时间做随机数种子
int range,n;
int min=2,flag=0;
time_t t;
double j;
srand((unsigned)t);
n=rand();
j=((double)n/(double)RAND_MAX);
n=(int)(j(double)range);
n+=min;
return n;
}int co_prime(int a ,int b) // 求互质
{int c;
do
{if(b==1)
return 1;
c=a%b;
a=b;
b=c;
}while(c!=0);
return 0;
}void get_d_e(int p,int q)
{int r,t,e,d,i=2,k=0;
{printf("Invaild Parametersnshould be PRIME!n");
printf("Usage:RSA Prime1 Prime2n");
exit(0);
t=(p-1)(q-1);
while(co_prime(t,e)!=1)
{e=e+1;
}for(d=2;d {if((ed)%t==1) break; }printf("d=%d e=%d r=%dn",d,e,r); }void en(int n,int e,int r) {//加密 }void de(int c,int d,int r) {//解密 }void main(int argc,char argv[]) {int n1,n2; {printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express e rn"); printf("RSA -d Ciphertext d rn"); printf("RSA Prime1 Prime2n");//错误输出 exit(0); }else {n1=str2num(argv[1]); n2=str2num(argv[2]); get_d_e(n1,n2); exit(0); }else if(argv[1][1]=='e') //加密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }if(argv[1][1]=='d') //解密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }else{ printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express e rn"); printf("RSA -d Ciphertext d rn"); printf("RSA Prime1 Prime2n"); exit(0); }} #include #include #include #include #include int str2num(char str) //字符转数字 {int i=0,num=0; for(i=0;i<(int)strlen(str);i++) return num; }float CarmSqrt(float x) //求平方根 系统的太慢,用了别人的 {union {int intPart; float floatPart; }convertor; union {int intPart; float floatPart; }convertor2; convertor.floatPart = x; convertor2.floatPart = x; convertor.intPart = 0x1FBCF800 + (convertor.intPart >> 1); convertor2.intPart = 0x5f3759df - (convertor2.intPart >> 1); return 0.5f(convertor.floatPart + (x convertor2.floatPart)); }//可以不用,用sqrt()也可以 int isPrime(int n) //判断是否为素数 {int i=0,k=2; k=(int)CarmSqrt(n); {if(n%i==0) break; }if(i>k) return 1; else return 0; }int rnd(int max) //生成随机数 2~max 用来生成e, { //取系统时间做随机数种子 int range,n; int min=2,flag=0; time_t t; double j; srand((unsigned)t); n=rand(); j=((double)n/(double)RAND_MAX); n=(int)(j(double)range); n+=min; return n; }int co_prime(int a ,int b) // 求互质 {int c; do {if(b==1) return 1; c=a%b; a=b; b=c; }while(c!=0); return 0; }void get_d_e(int p,int q) {int r,t,e,d,i=2,k=0; {printf("Invaild Parametersnshould be PRIME!n"); printf("Usage:RSA Prime1 Prime2n"); exit(0); t=(p-1)(q-1); while(co_prime(t,e)!=1) {e=e+1; }for(d=2;d {if((ed)%t==1) break; }printf("d=%d e=%d r=%dn",d,e,r); }void en(int n,int e,int r) {//加密 }void de(int c,int d,int r) {//解密 }void main(int argc,char argv[]) {int n1,n2; {printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express e rn"); printf("RSA -d Ciphertext d rn"); printf("RSA Prime1 Prime2n");//错误输出 exit(0); }else {n1=str2num(argv[1]); n2=str2num(argv[2]); get_d_e(n1,n2); exit(0); }else if(argv[1][1]=='e') //加密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }if(argv[1][1]=='d') //解密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }else{ printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express e rn"); printf("RSA -d Ciphertext d rn"); printf("RSA Prime1 Prime2n"); exit(0); } #include #include #include #include #include int str) //字符转数字 {int i=0,num=0; for(i=0;i<(int)strlen(str);i++) return num; }float CarmSqrt(float x) //求平方根 {union {int float floatPart; }convertor; union {int float floatPart; }convertor2; convertor.floatPart =x; convertor2.floatPart =x; convertor.intPart =0x1FBCF800 +(convertor.intPart >> 1); convertor2.intPart =0x5f3759df -(convertor2.intPart >> 1); return 0.5f(convertor.floatPart +(x convertor2.floatPart)); }//可以不用,用sqrt()也可以 int isPrime(int n) //判断是否为素数 {int i=0,k=2; k=(int)CarmSqrt(n); {if(n%i==0) break; }if(i>k) return 1;aes.Key = pwdBytes; else return }int rnd(int max) //生成随机数 2~max 用来生成e, {//取系统时间做随机数种子 int range,n; int min=2,flag=0; time_t t; double j; srand((unsigned)t); n=rand(); j=((double)n/(double)RAND_MAX); n=(int)(j(double)range); n+=min; return n; }int co_prime(int a,int b) // 求互质 {int c; do {if(b==1) return 1; c=a%b; a=b; b=c; }while(c!=0); return }void get_d_e(int p,int q) {int r,t,e,d,i=2,k=0; {printf("Invaild Parametersnshould be PRIME!n"); printf("Usage:RSA Prime2n"); exit(0); t=(p-1)(q-1); while(co_prime(t,e)!=1) {e=e+1; }for(d=2;d {if((ed)%t==1) break; }printf("d=%d e=%d r=%dn",d,e,r); }void en(int n,int e,int r) {//加密 }void de(int c,int d,int r) {//解密 }void main(int argc,char argv[]) {int n1,n2; {printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express ern"); printf("RSA -d drn"); printf("RSA Prime2n");//错误输出 exit(0); }else {n1=str2num(argv[1]); n2=str2num(argv[2]); get_d_e(n1,n2); exit(0); }else if(argv[1][1]=='e') //加密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }if(argv[1][1]=='d') //解密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }else{ printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express ern"); printf("RSA -d drn"); printf("RSA Prime2n"); exit(0); }} #include #include #include #include #include int str) //字符转数字 {int i=0,num=0; for(i=0;i<(int)strlen(str);i++) return num; }float CarmSqrt(float x) //求平方根 {union {int float floatPart; }convertor; union {int float floatPart; }convertor2; convertor.floatPart =x; convertor2.floatPart =x; convertor.intPart =0x1FBCF800 +(convertor.intPart >> 1); convertor2.intPart =0x5f3759df -(convertor2.intPart >> 1); return 0.5f(convertor.floatPart +(x convertor2.floatPart)); }//可以不用,用sqrt()也可以 int isPrime(int n) //判断是否为素数 {int i=0,k=2; k=(int)CarmSqrt(n); {if(n%i==0) break; }if(i>k) return 1; else return }int rnd(int max) //生成随机数 2~max 用来生成e, {//取系统时间做随机数种子 int range,n; int min=2,flag=0; time_t t; double j; srand((unsigned)t); n=rand(); j=((double)n/(double)RAND_MAX); n=(int)(j(double)range); n+=min; return n; }int co_prime(int a,int b) // 求互质 {int c; do {if(b==1) return 1; c=a%b; a=b; b=c; }while(c!=0); return }void get_d_e(int p,int q) {int r,t,e,d,i=2,k=0; {printf("Invaild Parametersnshould be PRIME!n"); printf("Usage:RSA Prime2n"); exit(0); t=(p-1)(q-1); while(co_prime(t,e)!=1) {e=e+1; }for(d=2;d {if((ed)%t==1) break; }printf("d=%d e=%d r=%dn",d,e,r); }void en(int n,int e,int r) {//加密 }void de(int c,int d,int r) {//解密 }void main(int argc,char argv[]) {int n1,n2; {printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express ern"); printf("RSA -d drn"); printf("RSA Prime2n");//错误输出 exit(0); }else {n1=str2num(argv[1]); n2=str2num(argv[2]); get_d_e(n1,n2); exit(0); }else if(argv[1][1]=='e') //加密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }if(argv[1][1]=='d') //解密 {n1=str2num(argv[3]); en(str2num(argv[2]),n1,n2); exit(0); }else{ printf("Invaild Parameters!n"); printf("Usage: nRSA -e Express ern"); printf("RSA -d drn"); printf("RSA Prime2n"); exit(0); } RSA公钥密码系统包括密钥生成、加密和解密三个步骤。具体作如下: 密钥生成 选择两个不同的质数p和q,并计算它们的积n=pq,此时n=187。 接下来计算欧拉函数φ(n)=(p-1)(q-1),由于p和q都是质数,所以φ(n)=(11-1)(17-1)=160。 选择一个整数e,1 计算e对于φ(produce_key();n)的模反元素d,即de≡1(mod φ(n)),可以使用扩展欧几里得算法求解,得到d=17。 最终得到公钥为(n,e)=(187,65537),私钥为(n,d)=(187,17)。 加密 对于明文m,将其转换为对应的整数,例如将8转换为数字8。 计算密文c=m^e(mod n),其中^表示乘方运算,即8^65537(mod 187),可以使用快速幂算法进行计算。 最t=time(NULL);终得到密文c=8。 解密 对于密文c,计算明文m=c^d(mod n),即8^17(mod 187),同样可以使用快速幂算法进行计算。 最终得到明文m=8。 因此,使用给定的p、q和明文8构建的RSA公钥密码系统加密后的密文为8,解密后的明文为8。 文件加密解密是开发中经常用到的一个功能点,常见于客户端项目,需要对配置数据、参数设置、数据字典等需要隐匿,来增强客户端的安全性。 本章我们介绍两种常见文件加密解密方法 1.自定义加密解密函数,思路是文件转成Byte[],对byte元素使用对称加密算法对齐加密。加密后的byte[]转成base64。解密文件使用base64加密的byte[]解密即可生成原文件。 2.使用 System.Security.Cryptography. RijndaelMad,这种加密需要提供32位密码和16位向量密码 //加密 string pwd = "gjhdjfhdjdkdssajdjfkdjfdlijfadsd" ; //32位,密码 string ivpwd = "gjhdjfhdjdkdssad" ; //16位,向量密码 RijndaelMad aes = new RijndaelMad(); byte [] pwdBytes = System.Text.Encoding.UTF8.GetBytes(pwd); aes.IV = Encoding.UTF8.GetBytes(ivpwd); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; byte [] readFilcout<<" to 18679376@qq ! "< ICryptoTransform transform = aes.CreateEncryptor(); byte [] fielBuffer = transform.TransformFinalBlock(readFileByte, 0, readFileByte.Length); //注意这里返回的是加密后的byte[] //解密 RijndaelMad aes = new RijndaelMad(); byte [] pwdBytes = System.Text.Encoding.UTF8.GetBytes(pwd); aes.IV = Encoding.UTF8.GetBytes(ivpwd); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; byte [] readFileByte = ReadByte(filePath); ICryptoTransform transform = aes.CreateDecryptor(); //注意这里返回的是解密后的byte[] byte [] fielBuffer = transform.TransformFinalBlock(readFileByte, 0, readFileByte.Length); 加密方式越复杂需要的计算量越大,速度相应会变慢;加密方式需要结合项目来做选择。客户端项目对于数据保密性较强建议使用RSA和 RijndaelMad 混合加密。 非对称加密主要用于两个场景,数据传输,签名。数据传输应用场景:古代每年都进行科举考试,考生(数据发送者)将写好(明文)的纸张交给收取试卷的太监(可能发生数据泄露的网络),然后由他转交给(数据接受者)来审阅。最开始相安无事,直到有一年太监偷看,将告诉某些王公贵族的公子。开始发现这个办法有缺陷,于是更改了流程,发给每个考生一把锁头(公钥),考试写完后将锁起来再交给太监,这样太监就没办法偷看了。有一把能打开这些箱子的钥匙(私钥),这样就保证了考生不会泄露。签名应用场景:有一帝(数据发送者)觉得东边匈奴太嚣张,发了一道圣旨(明文)给驻守边疆的大将军(数据接受者),匈奴太嚣张了你给我怼他。太监又去送信了,结果他勾结匈奴把圣旨改了,让大将军撤军。发现,这个不行啊,然后给你大将军一把钥匙(公钥),自己按照又配了很多对应的锁头。再次发圣旨的时候,就把圣旨的摘要锁起来。摘要很短,写了圣旨有多少字,主要内容等(其实是按照hash函数映射出的字段,并没有实际意义)。ps:不要问我为啥不锁圣旨,因为圣旨比较长,要用的盒子比较大,也就是说加密起来比较困难,而摘要就很短,锁进一个小盒子里就行了。就这样,大将军再次收到圣旨的时候,就会拿钥匙打开盒子中的摘要看看圣旨有没有被篡改。 这样进行两步for(i=2;i<=k;i++)信息确认: 1、盒子上的锁头能被打开证明这个圣旨确实是发的。 2、摘要的内容和圣旨一致,证明确实内容未被篡改过问题描述:。即保证2点:信息的来源,信息未被篡改。 非对称加密主要是将一个复杂的数学问题转化成为解密的必要。其中最重要的还是单向函数(one-way function)就是就是说一个函数f,如果知道x可以轻易的计算f(x)。但是知道f(x)却不能轻易算出x,并且这个函数还有一个与x有关的后门y (就是指如果知道y和f(x)就可以轻易的计算出x的值). 通常最简单的RSA加密解密过程如下: 1、如果al要向bob发一个信息。就先让bob选择一个后门参数y和N(N 为两个大质数p,q的乘积)。因为欧拉定理我们知道x^(p-1)(q-1) mod N= 1.所以f(x) = x^y 就是这样一个单向函数,因为f^(-1) (x)=x^((p-1)(q-1)-y) mod N 。然后bob将y和N发布出去作为公共密钥。 2、al 想要传递一个信息m。则计算f(m) mod N并发送给 Bob 3、Bob可以利用f^(-1)(f(m)) = m来获得想要的密文。这个加密算法之所以可以成功主要是N不容易被质数分解否则人人都可以计算f^(-1) 这个函数了。我自己有个比较形象的比喻。就是非加密算法就是别人想要发信息给你。你就先造一个保险箱。这个保险箱可以不用钥匙就可以关上。你把这个保险箱给别人。别人要给你发信息就把信息放进去然后锁上还给你。因为你有钥匙。所以你可以知道信息。那么要这个算法除非别人能从你的保险箱结构推算出你的钥匙的形状。或者干脆能撬开锁。至于自己设计非对称算法。关键还是要找到带后门的单项函数。没有怎么仔细想过这个问题。。但是如果不要求很安全的话。应该不是太难。。但是看不出必要性在什么地方。除非你的单项函数计算更简单。或者密钥所需要的长度更短。 这个是扩展的欧几里得算法 用于求一个数的逆元 RSA中也就是知道公钥enum=num10+str[i]-'0'; 求私钥d 欧几里得算法是求公约数的,求逆元用扩展的欧几里得算法 原理: 如果(a,b)=d,则存在m,n,使得d = ma + nb,称呼这种关系为a、b组合整数d,m,n称为组合系数。当d=1时,有 ma + nb = 1 ,此时可以看出m是a模b的乘法逆元,n是b模a的乘法逆元。 int (int a, int b , int&; ar,int &; br) {int x1,x2,x3; int y1,y2,y3; int t1,t2,t3; if(0 == a) {//有一个数为0,就不存在乘法逆元 ar = 0; br = 0 ; return b; }if(0 == b) {ar = 0; br = 0 ; return a; }x1 = 1;x2 = 0;x3 = a; y1 = 0;y2 = 1;y3 = b; int k; for( t3 = x3 % y3 ; t3 != 0 ; t3 = x3 % y3) {k = x3 / y3;t2 = x2 - k y2;t1 = x1 - k y1; x1 = y1;x1 = y2;x3 = y3; y1 = t1;y2 = t2;y3 = t3; }if( y3 == 1) { //有乘法逆元 ar = y2; br = x1; return 1; }else { //公约数不为1,无乘法逆元。这个是存在逆元的充要条件 ar = 0; br = 0; return y3; }} 核心是 for( t3 = x3 % y3 ; t3 != 0 ; t3 = x3 % y3) {k = x3 / y3;t2 = x2 - k y2;t1 = x1 - k y1; x1 = y1;x1 = y2;x3 = y3; y1 = t1;y2 = t2;y3 = t3; }一共str2num(char有三行 x1 ,x2 ,x3 y1 ,y2 ,y3 t1 ,t2 ,t3 每次循环第三行都是算出来的 然后 把行y的值放到x t的值放到y 这三行都满足一个共同的性质 个数a+第二个数b=第三个数 比如x1a+x2b=x3 每次循环问题都会简化,距离结果更进 直到 当最终t3迭代计算到1时,有t1× a + t2 × b = 1,显然,t1是a模b的乘法逆元,t2是b模a的乘法逆元。 坦白一点 今天我回答了3个RSA的问题 所以这个关于欧几里得的算法的解释 是我以前我回答他们的 也就是我抄袭的是自己的 当然这个算法不是我发明的 #include #include typedef int Elemtype; Elemtype p,q,e; Elemtype fn; Elemtype m,c; int flag = 0; typedef void (Msghandler) (void); struct MsgMap { char ch; Msghandler handler; }; / 公钥 / struct PU { Elemtype e; Elemtype n; } pu; / 私钥 / struct PR { Elemtype d; Elemtype n; } pr; / 判定一个数是否为素数 / bool test_prime(Elemtype m) { if (m <= 1) { return false; }else if (m == 2) { return true; }else { for(int i=2; i<=sqrt(m); i++) { if((m % i) == 0) { return false; break; }} return true; }} / 将十进制数据转化为二进制数组 / void switch_to_bit(Elemtype b, Elemtype bin[32]) { int n = 0; while( b > 0) { bin[n] = b % 2; n++; b /= 2; }} / 候选菜单,主界面 / void Init() { cout<<""< cout<<" Welcome to use RSA encoder "< cout<<" a.about "< cout<<" e.encrypt "< cout<<" d.decrypt "< cout<<" s.setkey "< cout<<" q.quit "< cout<<"byTerry"< cout<<"press a key:"< }/ 将两个数排序,大Prime1的在前面/ void order(Elemtype &in1, Elemtype &in2) { Elemtype a = ( in1 > in2 ? in1 : in2); Elemtype b = ( in1 < in2 ? in1 : in2); in1 = a; in2 = b; }/ 求公约数 / Elemtype (Elemtype a, Elemtype b) { order(a,b); int r; if(b == 0) { return a; }else { while(true) { r = a % b; a = b; b = r; if (b == 0) { return a; break; }} }} / 用扩展的欧几里得算法求乘法逆元 / Elemtype extend_euclid(Elemtype m, Elemtype bin) { order(m,bin); Elemtype a[3],b[3],t[3]; a[0] = 1, a[1] = 0, a[2] = m; b[0] = 0, b[1] = 1, b[2] = bin; if (b[2] == 0) { return a[2] = (m, bin); }if (b[2] ==1) { return b[2] = (m, bin); }while(true) { if (b[2] ==1) { return b[1]; break; }int q = a[2] / b[2]; for(int i=0; i<3; i++) { t[i] = a[i] - q b[i]; a[i] = b[i]; b[i] = t[i]; }} }/ 快速模幂算法 / Elemtype modular_multiplication(Elemtype a, Elemtype b, Elemtype n) { Elemtype f = 1; Elemtype bin[32]; switch_to_bit(b,bin); for(int i=31; i>=0; i--) { f = (f f) % n; if(bin[i] == 1) { f = (f a) % n; }} return f; }/ 产生密钥 / void produce_key() { cout<<"input two primes p and q:"; cin>>p>>q; while (!(test_prime(p)&&test_prime(q))){ cout<<"wrong input,please make sure two number are both primes!"< cout<<"input two primes p and q:"; cin>>p>>q; }; pr.n = p q; pu.n = p q; fn = (p - 1) (q - 1); cout<<"fn = "< cout<<"input e :"; cin>>e; while(((fn,e)!=1)) { cout<<"e is error,try again!"; cout<<"input e :"; cin>>e; }pr.d = (extend_euclid(fn,e) + fn) % fn; pu.e = e; flag = 1; cout<<"PR.d: "< cout<<"PU.e: "< }/ 加密 / void encrypt() { if(flag == 0) { cout<<"setkey first:"< }cout<<"input m:"; cin>>m; c = modular_multiplication(m,pu.e,pu.n); cout<<"c is:"< }/ 解密 / void decrypt() { if(flag == 0) { cout<<"setkey first:"< }cout<<"input c:"; cin>>c; m = modular_multiplication(c,pr.d,pr.n); cout<<"m is:"< }/ 版权信息 / void about() { cout<<""< cout<<" by Terry "< cout<<" Terry,technology supported by weizuo !"< cout<<" If you he any question, please mail "< cout<<" Comr of science and engineering "< cout<<" XiDian University 2010-4-29 "< cout<<""< cout< Init(); }/ 消息映射 / MsgMap Messagemap[] = { {'a',about}, {'s',produce_key}, {'d',decrypt}, {'e',encrypt}, {'q',NULL} }; / 主函数,提供循环 / void main() { Init(); char d; while((d = getchar())!='q') { int i = 0; while(Messagemap[i].ch) { if(Messagemap[i].ch == d) { Messagemap[i].handler(); break; }i++; }} } 设p=17 q=11,这两个数明显是一个素数,根据这2个素数,选择一个e值,e=7,关于e怎么选,一会儿在下面的算法里你就知道。设明文M=88,则开始如下算法: 1. 计算n=pq=187 2. 计算φ(n)=(p-1)(q-1)=160 3. 选择e,使用它与160互素且小于160,因此选e=7 4. 确定d,使de除160的余数为1,取d=23。 这样得到公钥PU={e,n}={7,187} 私钥={d,n}={23,187} 加密:密文C=M^e mod n=88^7 mod 187=11 解密:明文M=C^d mod n=88 一、混合加密的理由 a、前面提及了RSA加解密算法和DES加解密算法这两种加解密算法,由于随着计算机系统能力的不断发展,DES的安全性比它刚出现时会弱得多,追溯历史DES的案例层出不穷,一台实际的机器可以在数天内DES是让某些人相信他们不能依赖DES的安全性的方法。而相对于DES,RSA的安全性则相对高些,虽然RSA的案例也有,但其所付出的代价是相对大的(相对DES),如今RSA的密钥也在升级,这说明RSA的难度也在增大。 b、在RSA加解密算法中提及到RSA加密明文会受密钥的长度限制,这就说明用RSA加密的话明文长度是有限制的,而在实际情况我们要进行加密的明文长度或许会大于密钥长度,这样一来我们就不得不舍去RSA加密了。对此,DES加密则没有此限制。 鉴于以上两点(个人观点),单独的使用DES或RSA加密可能没有办法满足实际需求,所以就采用了RSA和DES加密方法相结合的方式来实现数据的加密。 其实现方式即: 1、信息(明文)采用DES密钥加密。 2、使用RSA加密前面的DES密钥信息。 最终将混合信息进行传递。 而接收方接收到信息后: 1、用RSA解密DES密钥信息。 2、再用RSA解密获取到的密钥信息解密密文信息。 最终就可以得到我们要的信息(明文)。 二、实现例子: 结合前面RSA和DES加密: //}r=pq;/ /// RSA和DES混合加密 /// /// 待加密数据 /// RSA公钥 /// public Param Encrypt(string data, string publicKey) {//加密数据 DESSecurity DES = new DESSecurity(); string DESKey = DES.GenerateKey(); string encryptData = DES.Encrypt(data, DESKey); //加密DESkey RSASecurity RSA = new RSASecurity(); string encryptDESKey = RSA.Encrypt(DESKey, publicKey); Param mixParam = new Param(); mixParam.DESKey = encryptDESKey; mixParam.Data = encryptData; return mixParam; }/// /// RSA和DES混合解密 /// /// 待解密数据 /// 带解密的DESKey /// RSA私钥 /// public string Decrypt(string data, string key, string privateKey) {//解密DESKey RSASecurity RSA = new RSASecurity(); string DESKey = RSA.Decrypt(key, privateKey); //解密数据 DESSecurity DES = new DESSecurity(); return DES.Decrypt(data, DESKey); #incle=rnd(t)/10;ude #include #include #include #include int main(int argc, char argv[]) {printf("openssl_test begin "); RSA rsa=NULL; char originstr[]="hello "; //这是我们需要加密的原始数据 //allocate RSA structure,首先需要申请一个RSA结构题用于存放生成的公私钥,这里rsa就是这个结构体的指针 rsa = RSA_new(); if(rsa==NULL) {printf("RSA_new failed "); return -1; }//generate RSA keys BIGNUM exponent; exponent = BN_new(); //生成RSA公私钥之前需要选择一个奇数(odd number)来用于生成公私钥 if(exponent ==NULL) {printf("BN_new failed "); goto FAIL1; }if(0==BN_set_word(exponent,65537)) //这里选择奇数65537 {printf("BN_set_word failed "); goto FAIL1; }//这里modulus的长度选择4096,小于1024的modulus长度都是不安全的,容易被 if(0==RSA_generate_key_ex(rsa,4096,exponent,NULL)) {printf("RSA_generate_key_ex failed "); goto FAIL; }char cipherstr = NULL; //分配一段空间用于存储加密后的数据,这个空间的大小由RSA_size函数根据rsa算出 cipherstr = malloc(RSA_size(rsa)); if(cipherstr==NULL) {printf("malloc cipherstr buf failed "); goto FAIL1; }//下面是实际的加密过程,一个参数padding type,有以下几种。 / RSA_PKCS1_PADDINGPKCS #1 v1.5 padding. This currently is the most widely used mode. RSA_PKCS1_OAEP_PADDING EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty encoding parameter. This mode is recommended for all new applications. RSA_SSLV23_PADDING PKCS #1 v1.5 padding with an SSL-specific modification that denotes that the server is SSL3 capable. RSA_NO_PADDING Raw RSA encryption. This mode should only be used to implement cryptographically sound padding modes in the application code. Encrypting user data directly with RSA is insecure. / //这里首先用公钥进行加密,选择了RSA_PKCS1_PADDING if(RSA_size(rsa)!=RSA_public_encrypt(strlen(originstr)+1,originstr,cipherstr,rsa,RSA_PKCS1_PADDING)) {printf("encryption failure "); goto FAIL2; }printf("the original string is %s ",originstr); printf("the encrypted string is %s ",cipherstr);
//Now, let's decrypt the string with private key //下面来用私钥解密,首先需要一个buffer用于存储解密后的数据,这个buffer的长度要足够(小于RSA_size(rsa)) //这里分配一个长度为的字符数组,应该是够用的。 n2=str2num(argv[4]);char decrypted_str[]; int decrypted_len; if(-1=(decrypted_len=RSA_private_decrypt(256,cipherstr,decrypted_str,rsa,RSA_PKCS1_PADDING))) {printf("decryption failure "); goto FAIL2; }printf("decrypted string length is %d,decryped_str is %s ",decrypted_len,decrypted_str); FAIL2: free(cipherstr); BN_free(exponent); FAIL: RSA_free(rsa); return 0; }以上是源代码,下面使用下面的编译命令在源码所在路径下生成可执行文件 gcc .c -o openssl_test -lcrypto -ldl -L/usr/local/ssl/lib -I/usr/local/ssl/include 其中,-lcrypto和-ldl是必须的,前者是OpenSSL中的加密算法库,后者是用于成功加载动态库。 RSA是一种非对称加密算法,它使用一对密钥:公钥和私钥。公钥用于加密数据,私钥用于解密数据。私钥是保密的,只有拥有私钥的人可以解密使用公钥加密的数据。 公钥加密和私钥加密在RSA算法中有以下区别: 1. 公钥加密:使用接收者的公钥对数据进行加密。任何人都可以使用公钥加密数据,但只有接收者拥有相应的私钥才能解密数据。这种方式适用于保证数据的机密性,即只有接收者能够解密数据。 2. 私钥加密:使用发送者的私钥对数据进行加密。私钥加密通常用于数字签名,发送者使用私钥对数据进行加密,接收者可以使用发送者的公钥进行解密验证。这种方式适用于验证数据的完整性和身份认证,即接收者可以确信数据来自发送者,并且数据在传输过程中没有被篡改。 总结起来,公钥加密用于保证数据的机密性,只有接收者可以解密数据;私钥加密用于数据的完整性和身份认证,接收者可以使用发送者的公钥进行解密验证。设 p=11 , q=17 , n=1117=187, 请构建一个RSA公钥塞码系统,并对明文8加?
面向对象基础知识之文件加密解密
if(argc!=3&&argc!=5)非对称加密的设计原理是什么?
急求助,在线等RSA加密解密算法的问题
给出p、q、e、M,求公钥,私钥,并且利用RSA算法加密和解密?
cout<<" copyright 2010,All rights reserved by "<如何使用RSA 和 DES 算法 对数据加密?
求得的m即为对应于密文c的明文。如何利用OpenSSL库进行RSA加密和解密
rsa私钥加密和公钥加密有什么区别
可以验证:(e·d) mod (p-1)(q-1) = 81 mod 40 = 1;
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系 836084111@qq.com 删除。