RSA算法實現(Python版)

加密={對稱加密,非對稱加密}

對稱加密的效率高於非對稱加密。常用對稱加密算法協商非對稱加密的密鑰,便於用非對稱加密傳輸數據。

非對稱加密算法有很多種實現算法,RSA是其中一種(三個人姓氏首字母的縮寫,其中R和S想算不可逆公式one-way function,數學家A尋公式的不足)。

非對稱加密算法步驟:生成密鑰對,分發公鑰,加密,解密。用途:加密傳輸,數字簽名。

RSA是基於離散對數的實現,設計和證明移步維基百科RSA。以下是我看了百科後自己用Python3嘗試的代碼清單。

import random

class RSA:
    def is_prime(self, n):
        '''primality test'''
        if n <= 3:
            return n > 1
        elif (n % 2 == 0) or (n % 3 == 0):
            return False
        i = 5
        while i * i <= n:
            if (n % i == 0) or (n % (i + 2) == 0):
                return False
            i += 6
        return True
    
    def gcd(self, a, b):
        '''返回a、b的最大公約數'''
        return a if b == 0 else self.gcd(b, a % b)
    
    def lcm(self, a, b):
        '''返回a、b的最小公倍數'''
        return a // self.gcd(a, b) * b
    
    def ex_gcd(self, a, b, d, x, y):
        '''
        函數結束時,(x + b) % b爲 (a % b)的乘法逆元
        '''
        if b == 0:
            d[0], x[0], y[0] = a, 1, 0
        else:
            self.ex_gcd(b, a % b, d, y, x)
            y[0] -= a // b * x[0]
    
    def quick_power(self, a, b, mod):
        res = 1
        while b != 0:
            if (b & 1) == 1:
                res = (res * a) % mod  
            a = a * a % mod
            b >>= 1
        return res       

    def generate(self):
        '''
        Generates a k-bit RSA public/private pair
        @param 
        @returns 返回密鑰對
        '''
        p, q = 10000079, 10000943  
        # p、q互質,他來決定了模數n的大小,消息可被轉化爲不大於n的數加密
        # 其實可以給函數加一個參數,來約束p、q的大小
        lambdan = self.lcm(p - 1, q - 1)
        e = 0
        while not self.is_prime(e):
            e = random.randint(2, lambdan - 1)
        d = [0]
        self.ex_gcd(e, lambdan, [0], d, [0]) 
        d = d[0] % lambdan
        return {
            'n': p * q,  # public key (part I)
            'e': e,      # public key (part II)
            'd': d,      # private key
        } 

    def encrypt(self, m, e, n):
        '''
        明文m,指數e,模數n 
        '''
        c = self.quick_power(m, e, n)
        return c
    
    def dencypt(self, c, d, n):
        m = self.quick_power(c, d, n)
        return m
        

if __name__ == "__main__":
    alice = RSA()
    bob = RSA()
    keys = alice.generate()
    msg = 878089
    '''bob使用alice的公鑰加祕明文,alice收到密文後使用私鑰解密'''
    c = bob.encrypt(m=msg, e=keys['e'], n=keys['n'])
    m = alice.dencypt(c, d=keys['d'], n=keys['n'])
    assert msg == m
    print(msg, m)

 

既來之,則安之。要開學選課了,我估計的得主修網絡空間安全了,將來從事運維,無緣開發崗(還是會偷偷學Java的)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章