【快速学】RSA数字签名(非对称加密算法)

RSA算法,如何使用

  1. 通过一个例子说明非对称加密的过程:
  2. 假设A,B两人进行公钥加密通信,A为信息发出者。
  3. B首先通过算法生成密钥对(包含公钥,私钥),之后将公钥发送给A,B保留私钥。
  4. A使用B发送来的公钥对信息进行加密,将密文发送给B,B利用自己的私钥对密文进行解密。

RSA算法生成密钥流程

  1. 给定两个质数p,q(p,q很大,不相等)
  2. 求出n=p*q
  3. 求出φ=(p-1)*(q-1)(不大于n,且与n互质的自然数)
  4. 找到一个符合条件的e(e<n 且 e与φ互质)
  5. 用辗转相除法求出x: 满足ex-1被φ整除(扩展欧几里得算法)
  6. 得到公钥(n, e),私钥(n, φ)
  7. 对信息A加密后生成R:R = Ae mod n
  8. 对信息R解密后生成A:A = Rx mod n

RSA算法程序

/*
RSA加密算法
*/
#include<iostream>
#include<cstring>
using namespace std;
class RSA
{
    private:
        static const  int MAX = 1e3;//常量
        char PlaintText[MAX] = {}; //明文
        int Plaint[MAX] = {}; //明文(数字)
        char CipherText[MAX] = {}; //密文
        int Cipher[MAX] = {}; //密文(数字)
        int len;
        //生成密钥需要的变量
        int p, q;
        int n;
        int e, x = 0, phi, y = 0;
        //判断一个数是否是质数
        bool isPrime(int n)
        {
            if (n <= 1)
            {
                return false;
            }
            for (int i = 2; i <= n / 2; ++i)
            {
                if (n % i == 0)
                {
                    return false;
                }
            }
            return true;
        }
        //求a,b的最大公因数
        int gcd(int a, int b)
        {
            return b == 0 ? a : gcd(b, a % b);
        }
        //扩展欧几里得算法ax+by=1
        int exgcd(int a, int b, int &x, int &y)
        {
            if (b == 0)
            {
                x = 1;
                y = 0;
                return a;  //到达递归边界开始向上一层返回
            }
            int r = exgcd(b, a % b, x, y);
            int temp = y;  //把x y变成上一层的
            y = x - (a / b) * y;
            x = temp;
            return r;     //得到a b的最大公因数
        }
        //求x的y次方(mod n))
        int PowModN(int x, int y)
        {
            long long ret = 1;
            if (x == 0)
                return 0;
            else
            {
                while (y--)
                {
                    ret *= x;
                    ret = ret % n;
                }

                return ret;
            }
        }
        //对数字A加密
        int CodeOne(int A)
        {
            return PowModN(A, e);
        }
        //对数字R解密
        int DeCodeOne(int R)
        {
            return PowModN(R, x);
        }
    public:
        //生成密钥
        bool calcKey()
        {
            cout << "==================生成密钥===================" << endl;
            cout << "请输入p:";
            cin >> p;
            if (!isPrime(p))
            {
                cout << "p不是素数" << endl;
                return false;
            }
            cout << "请输入q:";
            cin >> q;
            if (!isPrime(q))
            {
                cout << "q不是素数" << endl;
                return false;
            }
            cout << "===============生成密钥中=================" << endl;
            n = p * q;
            phi = (p - 1) * (q - 1);
            cout << "n=" << n << endl;
            cout << "phi=" << phi << endl;
            for (int i = 2; i < n; i++)//找到一个e,e与phi互质,并求出符合条件的x,y
            {

                if (gcd(i, phi) == 1)
                {
                    e = i;
                    exgcd(e, phi, x, y); //扩展欧几里得算法,求x,y
                    if (x > 0)
                    {
                        cout << "e=" << e << endl;
                        printf("e=%d,x=%d,phi=%d,y=%d\n", e, x, phi, y);
                        cout << "公钥:(" << n << "," << e << ")" << endl;
                        cout << "私钥:(" << n << "," << x << ")" << endl;
                        break;
                    }
                }
            }
            cout << "===============密钥生成完毕===============" << endl;
            return true;
        }
        //对字符串加密
        void Code()
        {
            cout << "请输入明文:" << endl;
            cin >> PlaintText;
            len = strlen(PlaintText);
            for (int i = 0; i < len; i++)
            {
                Plaint[i] = PlaintText[i];
                Cipher[i] = CodeOne(Plaint[i]);
                CipherText[i] = Cipher[i];
            }
        }
        //对字符串解密
        void DeCode()
        {
//            cout << "请输入密文:" << endl;
//            cin>>CipherText;
            for (int i = 0; i < len; i++)
            {
                Plaint[i] = DeCodeOne(Cipher[i]);
                PlaintText[i] = Plaint[i];
            }
        }
        //输出明文
        void PrintPlaintText()
        {
            cout << PlaintText << endl;
        }
        //输出密文
        void PrintCipherText()
        {
            cout << CipherText << endl;
        }
        //输出明文(数字)
        void PrintPlaint()
        {
            for (int i = 0; i < len; i++)
            {
                cout << Plaint[i] << " ";
            }
            cout << endl;
        }
        //输出密文(数字)
        void PrintCipher()
        {
            for (int i = 0; i < len; i++)
            {
                cout << Cipher[i] << " ";
            }
            cout << endl;
        }
};
int main()
{
    RSA r;
    while (r.calcKey()) //生成密钥成功,才加密解密
    {

        r.Code();//加密
        cout << "      明文:";
        r.PrintPlaintText();
        cout << "明文(数字):";
        r.PrintPlaint();
        cout << "加密后\n密文(数字):";
        r.PrintCipher();
        cout << "      密文:";
        r.PrintCipherText();
        r.DeCode();//解密
        cout << "对上面密文解密后\n明文(数字):";
        r.PrintPlaint();
        cout << "      明文:";
        r.PrintPlaintText();
    }

    return 0;
}

参考资料

https://www.bilibili.com/video/BV1sZ4y1H7WC

https://blog.csdn.net/destiny1507/article/details/81750874

posted @ 2023-05-12 22:20  尚方咸鱼  阅读(70)  评论(0编辑  收藏  举报