RSA简单讲解

RSA是一种非对称加密算法,基于欧拉定理和费马小定理。它涉及到两个大素数p和q的乘积n以及欧拉函数Φ(n),通过选取互素的e和计算d来形成公钥和私钥。加密过程是将明文用公钥e加密成密文,解密则是用私钥d对密文进行解密。RSA的安全性依赖于大数分解的难度,目前广泛用于网络安全领域。

假如有一天,Alice和Bob想要加密通讯,发信人找到一种非对称的加密算法RSA,并向你求助。

那么RSA原理如何,究竟如何进行一次基于RSA加密与解密呢?下面进行简单讲解。

目录

RSA名字由来

代数引入

加密与解密(非对称)

转化原理

证明欧拉定理

证明费马小定理

C++简单实现

关于RSA安全性及讨论


RSA名字由来

RSA名字是由三个开发者的姓名首字母组合而得来的,分别是Ron Rivest,Adi Shamir和Leonard Adleman

代数引入

首先我们选取两个大素数p和q(不能太接近)并计算n=p*q

利用欧拉函数计算Φ(n)=(p-1)(q-1),选取一个合适的e,其中e满足:

1<e<Φ(n),gcd(e,Φ(n))=1(e与Φ(n)互素)

此时e与n便是我们的公钥

计算d使得e*d mod Φ(n) = 1

这里因为e与Φ(n)互素,再根据欧拉定理,符合条件的d必然存在

利用公式 d=\frac{\Phi (n)*k+1}{e}( k\in N^{+})计算得d

此时d与n便是我们的私钥

加密与解密(非对称)

M(明文)是我们要加密和传输的信息,C(密文)是我们由明文加密得到的字段

加密步骤:M^{e}\;mod\; n = C

解密步骤:C^{d}\;mod\;n = M

转化原理

C^{d}\\=(M^{e}\;mod\;n)^{d}\\=M^{e*d}\;mod\;n \\= M^{k*\Phi (n)+1}\;mod\;n\\=M*(M^{\Phi (n)})^{k}\;mod\;n\\=M*(1\;mod\;n)\;mod\;n\\=M\;mod\;n\\=M

其中k\in N^{+}M<n

引入了公式:

a\;mod\;n*b\;mod\;n=a*b\;mod\;n(1)

a^{\Phi(n)}=1\;mod\;n(2)(欧拉定理)

证明欧拉定理

        若正整数 a , n 互质,则 a^{\Phi(n)}≡1(mod n)   其中 φ(n) 是欧拉函数,其值为1~n 中与 n 互质的数的个数。

不妨设X1,X2 ...... Xφn是1~n与n互质的数。

首先我们先来考虑一些数:a*X1,a*X2 ...... a*Xφn

这些数有如下两个性质:

(1)任意两个数模n余数一定不同:

反证法:若存在a*X1≡a*X2(mod n),则 n |(a*X1 - a*X2 ),而a,n互质且(X1 - X2)< n,所以n不可能整除( a*X1 - a*X2 ),也就是说不存在a*X1≡a*X2(mod n)。归纳法:对于任意的与n互质的Xi均成立。故得证。

那么因为有 φ(n) 个这样的数,Xi mod n(i=1~φ(n))所以就有 φ(n) 个不同的余数,并且都是模数自然是(0~n-1)。

(2)对于任意的a*Xi(mod n)都与n互质。这不难想,因为a与n互质这是欧拉函数的条件,Xi是(1~n)与n互质的数的集合中的元素。所以如果a*Xi做为分子,n做为分母,那么他们构成的显然就是一个最简分数,也就是aXi和n互质。接下来就可以用欧几里得算法:

因为:gcd(a*Xi,n)= 1

所以:gcd(a*Xi,n)= gcd(n,a*Xi%n)= 1

这样,我们把上面两个性质结合一下来说,a*X1(mod n),a*X2(mod n) ...... a*Xφn(mod n)构成了一个集合(性质1证明了所有元素的互异性),并且这些数是1~n与n互质的所有数构成的集合(性质1已说明)。由此,我们巧妙的发现了,集合{ a*X1(mod n),a*X2(mod n) ...... a*Xφn(mod n)}经过一定的排序后和集合{ X1,X2 ...... Xφn }一一对应。那么:a*X1(mod n)* a*X2(mod n)*  ...... * a*Xφn(mod n)= X1 * X2 * ...... * Xφn   因此:我们可以写出以下式子:

a*X1 * a*X2 *  ...... * a*Xφn ≡  X1 * X2 * ...... * Xφn  (mod n),即:(a^{\Phi(n)} -1)*X1 * X2 * ...... * Xφn ≡ 0 (mod n)

又因为X1 * X2 * ...... * Xφn与n互质,所以, (a^{\Phi(n)} -1)| n,那么a^{\Phi(n)} ≡ 1(mod n)。欧拉定理得证。 

证明费马小定理

  对于质数p,任意整数a,均满足:a^{p}≡a(mod p)

证明如下:

  这个可以用欧拉定理来说明:首先,我们把这个式子做一个简单变换得:a^{p}-1 * a ≡ a(mod p) 因为a ≡ a(mod p)恒成立,所以a^{p}-1 mod p == 1时费马小定理才成立,又因为p是质数,所以 φ(n) = n-1,所以根据欧拉定理:若a,p互质则a^{p}-1 mod p == 1成立。那么对于a,p不互质,因为p是质数,所以,a一定是倍数a^{p} ≡ a ≡ 0(mod p)。综上所述,费马小定理成立,它算是欧拉定理的一个特例。    

 

C++简单实现

测试数字较小时准确率较高

#include <iostream>
#include<algorithm>
#include <cmath>

using namespace std;
typedef long long ll;

// e是公钥
// d是私钥

ll e, d, n;

ll gcd(ll a, ll b)  //求最大公约数
{
    ll c = 0;
    if (a < b) swap(a, b);
    c = b;
    do
    {
        b = c;
        c = a % b;
        a = b;
    } while (c != 0);
    return b;
}

// 0不是 1是 
ll isPrime(ll i) //判断i是否是素数
{
    ll flag = 0;
    for (ll a = 2; a < i; a++)
    {
        if (i % a == 0)
        {
            flag = 1;
            break;
        }
    }
    if (flag == 1) return 0;
    else return 1;

}

ll myPow(ll a, ll b, ll n)  //求a^b mod n
{
    ll y;

    /*使用二进制平方乘法计算 pow(a,b) % n*/
    y = 1;

    while (b != 0)
    {
        /*对于b中的每个1,累加y*/

        if (b & 1)
            y = (y * a) % n;

        /*对于b中的每一位,计算a的平方*/
        a = (a * a) % n;

        /*准备b中的下一位*/
        b = b >> 1;
    }

    return y;

}

void extgcd(ll a, ll b, ll& d, ll& x, ll& y)
{
    if (!b)
    {
        d = a;
        x = 1;
        y = 0;
    }
    else
    {
        extgcd(b, a % b, d, y, x);
        y -= x * (a / b);
    }
}

ll ModularInverse(ll a, ll b)  //获取(1/a)mod b的结果
{
    ll d, x, y;
    extgcd(a, b, d, x, y);
    return d == 1 ? (x + b) % b : -1;

}

void KeyGeneration()  //获取公钥密钥
{
    ll p, q;
    ll phi_n;

    do
    {
        do
            p = rand();
        while (p % 2 == 0);

    } while (!isPrime(p)); 	// 得到素数 p 

    do
    {
        do
            q = rand();
        while (q % 2 == 0);
    } while (!isPrime(q)); 	// 得到素数q 

    n = p * q;
    phi_n = (p - 1) * (q - 1);

    do
        e = rand() % (phi_n - 2) + 2; // 1 < e < phi_n
    while (gcd(e, phi_n) != 1);

    d = ModularInverse(e, phi_n);
}

// 一位一位地输出加密的结果 
ll Encryption(ll value)  //加密
{
    ll cipher;
    cipher = myPow(value, e, n);
    cout << cipher;
    return cipher;
}

// 一位一位地输出解 密的结果 
void Decryption(ll value)  //解密
{
    ll decipher;
    decipher = myPow(value, d, n);
    cout << decipher;
}
int main()
{
    ll num;
    cout << "请输入要加密的明文数字,ctrl+c结束" << endl;
    while (cin >> num) {
        ll de;
        cout << "输入的明文为" << num << endl;
        KeyGeneration();  //获取公钥密钥
        cout << "加密密钥:" << e << endl;
        cout << "加密结果为:";
        de = Encryption(num);
        cout << "\n私钥为:" << d;
        //		cout<<"de="<<de<<endl;
        cout << "\n解密结果";
        Decryption(de);
        cout << "\n-------------" << endl;
    }
    return 0;
}

关于RSA安全性及讨论

根据前面说到的RSA算法原理,RSA的破解方法可以是找到私钥d,或者找到n的两个质因数p和q,然后根据φ(n)和公钥求得d。RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理论上的证明,也并没有从理论上证明破译RSA的难度与大数分解难度等价。 因为没有证明破解RSA就一定需要做大数分解。 RSA算法的安全强度随着其密钥长度的增加而增加,因此现在加密所采用的n一般在2048位二进制数。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JUICYYY33

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值