首页 密码学

1.RSA加密

1.1 RSA

RSA是目前使用最广泛的公钥密码体制之一。它是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA算法的安全性基于RSA问题的困难性,也就是基于大整数因子分解的困难性上。但是RSA问题不会比因子分解问题更加困难,也就是说,在没有解决因子分解问题的情况下可能解决RSA问题,因此RSA算法并不是完全基于大整数因子分解的困难性上的。

1.2 RSA为什么安全。

  • ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。
  • φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。
  • n=pq。只有将n因数分解,才能算出p和q。

2. 加密算法实现

2.1 加密过程

首选取两个互质数 p q
那么p * q 得到 N
这时我要计算出φ(N)
φ函数φ(N)是小于或等于N的正整数中与N互质的数的数目。

根据欧拉公式,我知道

φ(N) = (p-1)*(q-1)

这个公式简单的说就是 e*d除以φ(N)得到的余数为1

这个公式可以转换成

e*d - 1 = kφ(n)

所以,已知 e = 7 φ(n) = 120

7d - 120*k = 1
我们要获得d和k的话,需要使用扩展欧几里得算法
以下是扩展欧几里德算法的Python实现:


def ext_euclid(a, b):     
    if b == 0:         
        return 1, 0, a     
    else:         
        x, y, q = ext_euclid(b, a % b) 
        # q = gcd(a, b) = gcd(b, a%b)         
        x, y = y, (x - (a // b) * y)         
        return x, y, q

120 = 7 * 17 + 1
17 = 17 * 1
1 = 120 * 1 + 7 * (-17)
1 = 120 * 1 + 7 *(-17)
最终得出,d = -17 k = 1

虽然我们得到了 d=-17但 在rsa中 d必须是一个正整数,在工程中,RSA的pq会无穷大过公钥质数e ,所以根本不会出现这种状况。但是如果出现负数,我们会将它翻转

if(d<0)
    d=d+φ(n)

所以得到 e对φ(n)的模逆元 为 120 + (-17)也就是103

RSA中 公钥就是 N,e 而 私钥就是N,d

我们上面的例子 公钥 (143,7) 私钥(143, 103)

加密

m^e ≡ c (mod n)

要加密的m = 13

13^7 = 117 (mod 143)

解密

c^d ≡ m (mod n)

要解密的是c = 117

117^103 = 13 (mod 143)

上面可以用快速幂取余来计算出余数

c^d ≡ m (mod n)

#include <stdio.h>
long PowerMod (int a, int b, int c) {
    int  ans = 1;
    a = a % c;
    while(b>0) {
        if(b % 2 == 1)
            ans = (ans * a) % c;
        b = b/2;       //   b>>=1;
        a = (a * a) % c;
    }
    return ans;
}

2.2. Python实现

import math
# 在一次RSA密钥对生成中,假设p=473398607161,q=4511491,e=17
# 求解出d
# 第一步,随机选择两个不相等的质数p和q。
# 选择473398607161和4511491。(实际应用中,这两个质数越大,就越难破解。)
p = 473398607161
q = 4511491
# 第二步,计算p和q的乘积n。
n = p*q
# n的长度就是密钥长度。n写成二进制是111011...1011010101011,一共有63位,
# 所以这个密钥就是63位。实际应用中,RSA密钥一般是1024位,重要场合则为2048位。
# 第三步,计算n的欧拉函数[N]φ(n)。
N = (p-1)*(q-1)
# 第四步,随机选择一个整数e,条件是1< e < [N]φ(n),且e与φ(n) 互质。
# 这里选择e=17,可以在1<e<N里面选择
e=17
# 第五步,求d,就是计算e对于[N]φ(n)的模反元素d。
# 所谓"模反元素"就是指有一个整数d,可以使得ed被[N]φ(n)除的余数为1
#  ed - 1 = k*N,k是一个正整数
#  e*d ≡ 1 (mod N) 等价,这里使用扩展欧几里得算法实现,首先定义扩展欧几里得算法函数
def ext_euclid(a, b):#a==e,b==N
    if b == 0:
        return 1, 0, a
    else:
        x, y, q = ext_euclid(b, a % b)
        # q = gcd(a, b) = gcd(b, a%b)
        x, y = y, (x - (a // b) * y)
        return x, y, q
print(ext_euclid(e,N))

2.2 gmpy2库实现

gmpy2是一个C编码的Python扩展模块,它支持多精度算术。gmpy2是原始gmpy模块的后继者。

import gmpy2
p = 473398607161
q = 4511491
e = 17
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
print(d)



文章评论