实验内容:编程实现RSA算法,要求有密钥生成、加密步骤和解密步骤。

实验操作步骤

1、密钥生成

(1)任选两个不同的大素数𝑝和𝑞,计算𝑛=𝑝𝑞,𝜑(𝑛)=(𝑝−1)(𝑞−1)。

计算n=p*q,fy(n)=(p-1)(q-1)

(2)任选一个大整数𝑒,满足gcd(𝑒,𝜑(𝑛))=1,𝑒为公钥PK。

(3)作为私钥SK的𝑑,应满足𝑑𝑒 𝑚𝑜𝑑 𝜑(𝑛)=1,即𝑑𝑒=𝑘𝜑(𝑛)+1,其中,𝑘≥1且是整数。

       实验过程中,我发现当p和q取大整数时,计算d的过程很漫长,因此引入大整数幂取模算法,即蒙哥马利算法。当把mod N 转换为mod R时,a mod N需要转换为:aR mod N,aR称为整数a的蒙哥马利形式,对于加减法:aR±RSA的工作原理python rsa代码实现_RSA的工作原理pythonbR=(a±RSA的工作原理python rsa代码实现_python_02b)R,对于乘法,需要乘上R的逆元R’,即:((aR mod N)(bR mod N)mod N)R’=(aR)(bR)R’=(ab)RmodN。

(4)公开整数𝑛和𝑒,秘密保存𝑑。

2、加密步骤

将明文𝑚(𝑚<𝑛,是一个整数)加密成密文𝑐,加密算法为𝑐=𝐸(𝑚)=𝑚𝑒  𝑚𝑜𝑑 𝑛

3、解密步骤

将密文𝑐解密为明文𝑚,解密算法为𝑚=𝐷(𝑐)=𝑐𝑑  𝑚𝑜𝑑 𝑛

import math
from msvcrt import kbhit
import time
# 辗转相除法求a,b的最大公因数
def gcd(a, b):
    k=0
    while (1):
        k=a%b
        a=b
        b=k
        if(k==0):
            break
    return a

#扩展欧几里的算法计算 ax + by = 1中的x与y的整数解(a与b互质)
'''求解ax=1(mod b),就是求ax+by=1中x与y的整数解
求解乘法逆元d,(d*e=1 mod(fai),就是求d*e+fai*y=1的解'''
def ext_gcd(a, b):
    if b == 0:
        x1 = 1
        y1 = 0
        x=x1
        y=y1
        r = a
        return r, x, y
    else:
        r, x1, y1 = ext_gcd(b, a % b)
        x=y1
        y = x1 - a // b * y1

        return r, x, y


#蒙哥马利算法

def exp_mode(base, exponent, n):
    bin_array = bin(exponent)[2:][::-1]
    r = len(bin_array)
    base_array = []
    
    pre_base = base
    base_array.append(pre_base)
    
    for _ in range(r - 1):
        next_base = (pre_base * pre_base) % n 
        base_array.append(next_base)
        pre_base = next_base
        
    a_w_b = __multi(base_array, bin_array, n)
    return a_w_b % n

def __multi(array, bin_array, n):
    result = 1
    for index in range(len(array)):
        a = array[index]
        if not int(bin_array[index]):
            continue
        result *= a
        result = result % n # 加快连乘的速度
    return result


# 生成公钥私钥,p、q为两个超大质数
def gen_key(p, q):
    n = p * q
    fy = (p - 1) * (q - 1)                    
    a = e
    b = fy
    r, x, y = ext_gcd(a, b)
    # 计算出的x不能是负数,如果是负数,说明p、q、e选取失败,不过可以把x加上fy,使x为正数,才能计算。
    if x < 0:
        x = x + fy
    d = x
    print("d为-->",d)
    # 返回:   公钥     私钥
    return    (n, e), (n, d)
    
# 加密 m是被加密的信息 加密成为c
def encrypt(m, pubkey):
    n = pubkey[0]
    e = pubkey[1]
    
    c = exp_mode(m, e, n)
    return c

# 解密 c是密文,解密为明文m
def decrypt(c, selfkey):
    n = selfkey[0]
    d = selfkey[1]
    
    m = exp_mode(c, d, n)
    return m
    
    
if __name__ == "__main__":
    '''公钥私钥中用到的两个大质数p,q,都是1024位'''
    #p = 106697219132480173106064317148705638676529121742557567770857687729397446898790451577487723991083173010242416863238099716044775658681981821407922722052778958942891831033512463262741053961681512908218003840408526915629689432111480588966800949428079015682624591636010678691927285321708935076221951173426894836169
    #q = 144819424465842307806353672547344125290716753535239658417883828941232509622838692761917211806963011168822281666033695157426515864265527046213326145174398018859056439431422867957079149967592078894410082695714160599647180947207504108618794637872261572262805565517756922288320779308895819726074229154002310375209
    p=eval(input("请输入大素数p:"))
    q=eval(input("请输入与p互素的大素数q:"))
    print("n为-->",p*q)
    e=eval(input("请输入任意一个大整数e:"))
    '''生成公钥私钥'''
    pubkey, selfkey = gen_key(p, q)
    #print("d为-->",d)
    '''需要被加密的信息转化成数字,长度小于秘钥n的长度,如果信息长度大于n的长度,那么分段进行加密,分段解密即可。'''
    #m = 1356205320457610288745198967657644166379972189839804389074591563666634066646564410685955217825048626066190866536592405966964024022236587593447122392540038493893121248948780525117822889230574978651418075403357439692743398250207060920929117606033490559159560987768768324823011579283223392964454439904542675637683985296529882973798752471233683249209762843835985174607047556306705224118165162905676610067022517682197138138621344578050034245933990790845007906416093198845798901781830868021761765904777531676765131379495584915533823288125255520904108500256867069512326595285549579378834222350197662163243932424184772115345
    m=eval(input("请输入待加密的信息m:"))
    print("待加密信息-->%s" % m)
    '''信息加密,m被加密的信息,c是加密后的信息'''
    c = encrypt(m, pubkey)
    print("被加密后的密文-->%s" % c)
    '''信息解密'''
    d = decrypt(c, selfkey)
    print("被解密后的明文-->%s" % d)

实验结果

(1)p=11,q=13,e=17,m=24

RSA的工作原理python rsa代码实现_最大公因数_03

(2)p=885320963,q=238855417,e=65537,m=24

 

RSA的工作原理python rsa代码实现_取模_04

 (3)p=106697219132480173106064317148705638676529121742557567770857687729397446898790451577487723991083173010242416863238099716044775658681981821407922722052778958942891831033512463262741053961681512908218003840408526915629689432111480588966800949428079015682624591636010678691927285321708935076221951173426894836169,q=144819424465842307806353672547344125290716753535239658417883828941232509622838692761917211806963011168822281666033695157426515864265527046213326145174398018859056439431422867957079149967592078894410082695714160599647180947207504108618794637872261572262805565517756922288320779308895819726074229154002310375209,e=65537,m=24

RSA的工作原理python rsa代码实现_取模_05