C ++ implementation symmetric encryption RSA

Learning things safe so that they achieve the following asymmetric encryption algorithm RSA algorithm

According to the time of discovery because the principle Coding for too long without Coding, so it is Shousheng

So everything Baidu up, but found that the network above code is too complicated, not suitable for forced Coding, especially for my kind of people who do not bother to understand the sentence by sentence

Because according to the principle of simple Coding for a moment, can achieve a simple encryption and decryption RSP

Of course, the middle a little memory space garbage problem caused by asymmetric ,,,, this is a small problem, you can see on the line

Of course, I will put online the great God written Code stick in the back

For reference

/*
RSA非对称加密算法
公钥-私钥对进行加解密
准备:明文M,公钥PU={e, n},私钥PR={d, n}
准备两个非常大的素数p和q,乘积为 n = p*q, f(n) = (p-1)*(q-1)
找出一个与互f(n)为质数的自然数e,1<e<f(n)
计算d, d = 1/e mod f(n)
最终得到公钥PU = {e, n}, 私钥PR = {d, n}
加密过程为 C = M^e mod n
解密过程为 M = C^d mod n
*/

/*
****************程序流程图*********************
                   开始
                     |
            随机获取两个素数p与q
                    |
            找出与f(n)互为质数的自然数e
                    |
                计算获得d
                    |
            PU={e, n},私钥={d, n}
                    |
                RSA加密
                    |
                RSA解密
*/
#include <iostream>
#include<math.h>
#include<ctime>
#include<cstdlib>
#include <string>
#include<string.h>
using namespace std;



//将num转换为i二进制储存在bin_num中
int BinaryTransform(int num, int *bin_num){
    int i = 0;
    int mod = 0;

    while (num != 0)
    {
        mod = num%2;
        bin_num[i++] = mod;
        num >> 1;
    }
    
    return i;//返回二进制的位数
}

//辗转相除法求最大公因数
int Gcd(int a, int b){
    if(b == 0)
        return true;
    return Gcd(b, a%b);
}

//获取n的互质数 e ,即另外一个数与n的最大公因数为1
int Gete(int n)
{
    int another = n;//根据RSP算法的要求,e越大,加密效果越好
    int flag = 1;
    while (flag)
    {
       if(Gcd(n, ++another) == 1){
           flag = 0;
       }
    }

    return another;
}

//获取d, d与e关于f(n)同余
int Getd(int e, int n){
    return (1/e % n);
}

int Getpq()
{
    srand((unsigned)time(NULL));
    return (10 + rand()%100);//生成一个10-100的随机数
}

int p, q, n, f, d, e;
void Init_RSA(){
    //生成p, q, f(n), d, e
    p = Getpq();
    q = Getpq();
    n = p*q;
    f = (--p)*(--q);
    d = Getpq();
    e = Gete(d);

    cout<< "p = " << p << endl
         << "q = " << q << endl
         << "n = " << n << endl
         << "f(n) =" << f <<endl
         << "d = " << d << endl
         << "e = " << e <<endl
         << "PU = {" << e << ", " << n <<"}" << endl
         << "PR = {" << d << ", " << n <<"}" << endl;
}

int GetPow(int x, int y)
{
    while(y--){
        x *= x;
    }

    return x;
}

string text;                //加密内容
int Plaintext[100];         //明文
long long Ciphertext[1000]; //密文

//解密 m = c^d(mod n)
void GetPlaintext(int Ciphertext[], int num, int d, int n)
{
    char sp[3];
    char *res;
    int i = 0;
    while (num--)
    {
        int low = GetPow(*Ciphertext, n) % n;//将明文的每一位都进行加密
        sprintf(sp, "%02d", low);//格式化为两位
        strcat(res, sp);//拼接起来
    }   

    cout << Ciphertext <<"加密完成, 结果为:" << res << endl;
    *Ciphertext = {0};
}

//解密
void GetCiphertext(int *Plaintext, int num, int d, int n)
{
    char sp[3];
    char *res;
    int i = 0;
    while (num--)
    {
        int low = GetPow(Plaintext[i], n) % n;  //将明文的每一位都进行加密
        sprintf(sp, "%02d", low);               //格式化为两位
        strcat(res, sp);                        //拼接起来
    }

    cout << Plaintext << "解密完成, 结果为:" << res <<endl;
    *Plaintext = {0};
}

int main(int argc, char const *argv[])
{
    int text[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 20};
    if (text != NULL)
    {
        Init_RSA();
        GetPlaintext(text, sizeof(text) / sizeof(text[0]), d, n);
        system("pause");
    }
    
    
    return 0;
}
//另一种方式
#include<bits/stdc++.h>
using namespace std;
int Euler(int n)//欧拉函数 求1到n中有多少个整数与n互质
{
    int rs=1;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            rs*=(i-1);
            n/=i;
            while(n%i==0)
            {
                rs*=(i-1);
                n/=i;
            }
        }
    }
    if(n>1)
        rs*=(n-1);
    return rs;
}
int gcd(int a,int b)//求a,b的最大公约数
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
int check(int n)//判断n是不是素数
{
    if(n==1)
        return 0;
    if(n==2)
        return 1;
    for(int i=3;i*i<=n;i=i+2)
    {
        if(n%i==0)
            return 0;
    }
    return 1;
}
int gnerating_primes(int n)//产生小于等于n的第一个素数
{
    if(n%2==0)
        n--;
    for(int i=n;i>1;i=i-2)
    {
        if(check(i)==1)
            return i;
    }
    return -1;//表示没有小于等于n的素数
}
int multiplicative_inverse_element(int a,int r)//求a对于r的乘法逆元
{
    int rs=1;
    if(check(r)==1)//r是素数 采用费马小定理
    {
        for(int i=1;i<=r-2;i++)
            rs*=a,rs%=r;
    }else //r不是素数,采用欧拉定理的推论
    {
        int k=Euler(r)-1;
        for(int i=1;i<=k;i++)
            rs*=a,rs%=r;
    }
    return rs;
}
int get_pk(int w)
{
    int pk=2;
    for(pk=2;pk<w;pk++)
    {
        if(gcd(w,pk)==1)
            return pk;
    }
    return pk;
}
int square_multiplication(int x,int c,int r)//平方乘算法,x的c次方%r
{
    string str="";
    while(c)
    {
        str=(char)(c%2+'0')+str;
        c/=2;
    }
    int rs=x;
    int l=str.length();
    for(int i=1;i<l;i++)
    {
        if(str[i]=='0')
            rs=((rs%r)*(rs%r))%r;
        else
            rs=(((rs%r)*(rs%r))%r*x)%r;
    }
    return rs;
}
int main()
{
    int p=47;
    int q=61;

    int r=p*q;//公开模数
    cout<<"r="<<r<<endl;

    int w=Euler(r);//1到r中与r互质的数的个数

    //求得公钥
    int pk=get_pk(w);
    //pk=167;
    cout<<"公钥(pk,r):("<<pk<<","<<r<<")"<<endl;

    //求得私钥
    int sk=multiplicative_inverse_element(pk,w);
    cout<<"私钥(sk,r):("<<sk<<","<<r<<")"<<endl;

    int M=123456789;//明文
    int K=3;//K位一组

    int temp=1;
    for(int k=1;k<=K;k++)
        temp*=10;
    cout<<"密文:";
    for(int i=1;i<=K;i++)
    {
         cout<<square_multiplication(M%temp,pk,r)<<" ";
         M/=temp;
    }
    cout<<endl;

    return 0;
}
原文链接:https://blog.csdn.net/qq_39382769/article/details/88273253
//第三种方式
#include <iostream>
#include <cmath>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;


int Plaintext[100];//明文
long long Ciphertext[100];//密文
int n, e = 0, d;

//二进制转换
int BianaryTransform(int num, int bin_num[])
{

    int i = 0,  mod = 0;

    //转换为二进制,逆向暂存temp[]数组中
    while(num != 0)
    {
        mod = num%2;
        bin_num[i] = mod;
        num = num/2;
        i++;
    }

    //返回二进制数的位数
    return i;
}

//反复平方求幂
long long Modular_Exonentiation(long long a, int b, int n)
{
    int c = 0, bin_num[1000];
    long long d = 1;
    int k = BianaryTransform(b, bin_num)-1;

    for(int i = k; i >= 0; i--)
    {
        c = 2*c;
        d = (d*d)%n;
        if(bin_num[i] == 1)
        {
            c = c + 1;
            d = (d*a)%n;
        }
    }
    return d;
}

//生成1000以内素数
int ProducePrimeNumber(int prime[])
{
    int c = 0, vis[1001];
    memset(vis, 0, sizeof(vis));
    for(int i = 2; i <= 1000; i++)if(!vis[i])
    {
        prime[c++] = i;
        for(int j = i*i; j <= 1000; j+=i)
            vis[j] = 1;
    }

    return c;
}


//欧几里得扩展算法
int Exgcd(int m,int n,int &x)
{
    int x1,y1,x0,y0, y;
    x0=1; y0=0;
    x1=0; y1=1;
    x=0; y=1;
    int r=m%n;
    int q=(m-r)/n;
    while(r)
    {
        x=x0-q*x1; y=y0-q*y1;
        x0=x1; y0=y1;
        x1=x; y1=y;
        m=n; n=r; r=m%n;
        q=(m-r)/n;
    }
    return n;
}

//RSA初始化
void RSA_Initialize()
{
    //取出1000内素数保存在prime[]数组中
    int prime[5000];
    int count_Prime = ProducePrimeNumber(prime);

    //随机取两个素数p,q
    srand((unsigned)time(NULL));
    int ranNum1 = rand()%count_Prime;
    int ranNum2 = rand()%count_Prime;
    int p = prime[ranNum1], q = prime[ranNum2];

    n = p*q;

    int On = (p-1)*(q-1);


    //用欧几里德扩展算法求e,d
    for(int j = 3; j < On; j+=1331)
    {
        int gcd = Exgcd(j, On, d);
        if( gcd == 1 && d > 0)
        {
            e = j;
            break;
        }

    }

}

//RSA加密
void RSA_Encrypt()
{
    cout<<"Public Key (e, n) : e = "<<e<<" n = "<<n<<'\n';
    cout<<"Private Key (d, n) : d = "<<d<<" n = "<<n<<'\n'<<'\n';

    int i = 0;
    for(i = 0; i < 100; i++)
        Ciphertext[i] = Modular_Exonentiation(Plaintext[i], e, n);

    cout<<"Use the public key (e, n) to encrypt:"<<'\n';
    for(i = 0; i < 100; i++)
        cout<<Ciphertext[i]<<" ";
    cout<<'\n'<<'\n';
}

//RSA解密
void RSA_Decrypt()
{
    int i = 0;
    for(i = 0; i < 100; i++)
        Ciphertext[i] = Modular_Exonentiation(Ciphertext[i], d, n);

    cout<<"Use private key (d, n) to decrypt:"<<'\n';
    for(i = 0; i < 100; i++)
        cout<<Ciphertext[i]<<" ";
    cout<<'\n'<<'\n';
}


//算法初始化
void Initialize()
{
    int i;
    srand((unsigned)time(NULL));
    for(i = 0; i < 100; i++)
        Plaintext[i] = rand()%1000;

    cout<<"Generate 100 random numbers:"<<'\n';
    for(i = 0; i < 100; i++)
        cout<<Plaintext[i]<<" ";
    cout<<'\n'<<'\n';
}

int main()
{
    Initialize();

    while(!e)
        RSA_Initialize();

    RSA_Encrypt();

    RSA_Decrypt();

    return 0;
}

 

Published 43 original articles · won praise 44 · views 6602

Guess you like

Origin blog.csdn.net/qq_41582910/article/details/104852780