RSA加密算法

来源:互联网 发布:法国航空发动机知乎 编辑:程序博客网 时间:2024/06/15 22:02

第一步



选择两个大质数p和q,越大越好,然后计算它们的乘积

N=pq

接着计算N的欧拉函数
φN=φpφq=(p1)(q1)
(对正整数N,欧拉函数φ(N)是小于或等于N的正整数中与N互质的数的数目)
然后从随机选择一个整数e,要求e满足
0<e<φN

并且与φ(N)互质。
最后,就可以计算出秘钥d了,它满足:
ed1(mod(φN))

参见:
模逆元
扩展欧几里得算法
其中数e和N是公钥,用于加密信息,对所有使用者公开;数d和N是私钥,用于解密信息,用户自己保存。


第二步



信息发送者用对方的公钥e和N对发送的明文M进行加密运算可以获得加密信息C,对应的密文计算方法是:

C=MemodN


第三步



当信息的接收者接收到密文C后,采用私钥d和N进行解密获取明文信息M,对应的解密运算方法是:

M=CdmodN



由于在进行加密和解密的时候,要对明文或者密文进行幂的取模运算,求幂的结果往往很大,可能远远超出计算机处理的范围,所以必须简化计算方式。
对于任意整数b都可以用以下形式表示(n为b的二进制位个数,bi为实际二进制位,为0或者为1):

i=0n1bi2i=b020+b121+b222+...+bn12n1

ab就可以表示为:
ab=ab020+b121+b222+...+bn12n1=ab020×ab121×ab222××abn12n1

因此,可以用各项
abi2i={a2i,1,if bi is 1if bi is 0

的积来计算ab,也就是连续项a2i的积,其中跳过了那些二进制位bi为0的项。此外,我们可以只对前面项的计算结果进行平方来计算a2i,因为a2i=a2i12
所以可以从右到左扫描,把相应二进制位为1的项包括在累乘器中,每一步都进行取模就可以得到最后的结果。

c++模拟实现

#include<iostream>#include<cmath>#include<cstring>#include<ctime>#include<cstdlib>using namespace std;#define MAX 50long public_text[MAX];     //明文long private_text[MAX];    //密文int p = 521;int q = 941;         //因为只探究加密原理,所以此处的p和q直接指定为两个较小的素数int N = p * q;int e = 1777;                   //e与(p-1)*(q-1)互质int d = 0;int gcdEx(int a,int b,int & x,int & y)  //扩展欧几里德算法{    if(b == 0)    {        x = 1;        y = 0;        return a;    }    else    {        int r = gcdEx(b,a % b,x,y);        int temp = x;        x = y;        y = temp - a / b * y;        return r;    }}long mod(long a,int b,int N)  //快速幂取模算法{    long result = 1;    long temp = a;    while(b > 0)    {        if(b & 1 == 1)   //按位与,每次判断最低位是否为1        {            result = (result * temp) % N;        }        temp = (temp * temp) % N;        b >>= 1;        //右移1位    }    return result;}void init(){    cout << "明文为:" << endl;     srand(time(NULL));    for(int i = 0;i < MAX;i++)    {        public_text[i] = rand() % 500 + 200;  //生成200到700之间的随机数        cout << public_text[i] << " ";    }    cout << endl;    int on = (p - 1) * (q - 1);    int y = 0;    gcdEx(e,on,d,y);       if(d < 0)    {        d += on;    }    cout << "PK = (N,e) = (" << N << "," << e << ")" << endl;    cout << "SK = (N,d) = (" << N << "," << d << ")" << endl;}void RSA_Encrypt()     //加密{    cout << endl << "明文用公钥PK(" << N << "," << e << ")加密后的密文为:" << endl;    for(int i = 0;i < MAX;i++)    {        private_text[i] = mod(public_text[i],e,N);   //分别对每部分明文进行加密        cout << private_text[i] << " ";    }    cout << endl;}void RSA_Decrypt()    //解密{    cout << endl << "密文用私钥SK(" << N << "," << d << ")解密后的明文为:" << endl;    for(int i = 0;i < MAX;i++)    {        cout << mod(private_text[i],d,N) << " ";    //输出解密后的明文    }    cout << endl;}int main(int argc,char *argv[]){    init();    RSA_Encrypt();    RSA_Decrypt();    return 0;}

这里写图片描述

0 0
原创粉丝点击