RSA加密算法

第一步



选择两个大质数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 50

long 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值