Python實現RSA算法


1977年,三位數學家 Rivest、Shamir 和 Adleman 設計了一種算法,可以實現非對稱加密。算法用他們三個人的名字命名,叫做 RSA 算法。直到現在,RSA 算法仍是最廣泛使用的"非對稱加密算法"。毫不誇張地說,只要有計算機網絡的地方,就有 RSA 算法。

生成秘鑰

  • 選取大素數\(p,q\);計算\(n=pq\)以及n的歐拉函數\(φ(n) = φ(p) φ(q)=(p-1)(q-1)\)
  • 選擇一個\(e(1<e<φ (n))\),使得\(e\)\(φ (n)\)互素
  • 計算\(d\),使得\(ed≡1(modφ(n))\),繼而\((n,e)\)為公鑰發送到公鑰空間,\((n,d)\)為私鑰,自己妥善保存。

加密

假設明文為\(m\) ,則密文為\(c\), 加密公式為\(c = m^e mod n\)

解密

通過對明文\(m\)加密得密文為\(c\),解密公式為\(m=c^d mod n\)

python代碼如下:

def ex_gcd(a,b):
    """擴展歐幾里德算法"""
    if b == 0:
        return 1, 0
    else:
        q = a // b
        r = a % b
        s, t = ex_gcd(b, r)
        s, t = t, s-q*t
    return [s, t]


# 快速冪算法
def fast_expmod(a,e,n):
    """快速冪"""
    d = 1
    while e != 0:
        if(e & 1) == 1:
            d = (d * a) % n
        e >>= 1
        a = a * a % n
    return d


def make_key(p, q, e):
    """
    生成公私鑰
    參數1:大素數p
    參數2:大素數q
    參數3:隨機生成e,滿足 gcd(e,fin)
    返回值:[公鑰,私鑰]-------[[n,e],[n,d]]
    """
    n = p * q
    fin = (p-1) * (q-1)
    d = ex_gcd(e, fin)[0]      # 輾轉相除法求逆(廣義歐幾里得)
    while d < 0:
        d = (d+fin) % fin
    return [[n, e], [n, d]]


def encryption(key, data):
    """
    加密
    參數1:列表[n,e]----公鑰
    參數2:待價密數據
    返回值:密文
    """
    n, e = key
    plaintext = list(data)
    ciphertext = []
    for item in plaintext:
        ciphertext.append(fast_expmod(ord(item), e, n))
    return ciphertext


def decrypt(key, ciphertext):
    """
    解密
    參數1:key為私鑰
    參數2:密文數據
    返回值:明文
    """
    n, d = key
    plaintext = ''
    for item in ciphertext:
        plaintext += (chr(fast_expmod(item, d, n)))
    return plaintext


def make_p_q_e():
    """
    返回值:[p,q,e]
    """
    p = 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
    q = 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917
    e = 65537
    return [p, q, e]


def test():
    p, q, e = make_p_q_e()
    # 獲取數據
    plaintext = input("待加密數據:")
    # 公鑰、私鑰
    public_key, private_key = make_key(p, q, e)
    # 加密
    ciphertext = encryption(public_key, plaintext)
    print("加密后的數據:", ciphertext)
    # 解密
    plaintext = decrypt(private_key, ciphertext)
    print("解密后的數據:", plaintext)


test()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM