RSA加解密算法实现

加解密原理

一,生成公钥和私钥
  • 1,找到两个大素数盘p, q(并且中间相隔比较远)

  • 2,计算n = p*q(计算完这步后,就可以将p,q丢弃)

  • 3,计算 fan_N = (p-1)*(q-1)

  • 4,选择e,使得e与fan_N互素,并且小于fan_N,

  • 5,计算d, 并且满足d*e mod fan_N = 1 且 d < 160

    经过上述几步:就可以得到公钥PU = {e,n}和私钥PR = {d,n}

二,加解密
  • 加密:
  • 假设有明文M
  • 则密文为:C = M^e(mod n)

  • 解密
  • 密文 C
  • 计算M = C^d(mod n)

代码

# -*- coding: utf-8 -*-
"""
Created on Wed Dec 19 22:11:25 2018
RSA加解密算法
@author: HcflyAmbation
"""


class RSA:
    """
    RSA加密算法
    """
    def __init__(self):
        self.__create_key()
        pass
    
    def rsa_encrypt(self, plain_text):
        # 加密 plain_text < n
        return self.__quick_pow_mod(plain_text, self.__e, self.__n)
    
    def rsa_decrypt(self, cipher_text):
        # 解密
        return self.__quick_pow_mod(cipher_text, self.__d, self.__n)

    @staticmethod
    def __create_prime_list():
        # 生成一个素数列表

        l = list(range(2, 10000))
        for n, i in enumerate(l):
            for j in l[n + 1:]:
                if j % i == 0:
                    l.remove(j)
        return l

    def get_public_key(self):
        # 获取公钥
        return "自动生成公钥对:{%d, %d}"% (self.__e, self.__n)

    def get_private_key(self):
        # 获取私钥
        return "自动生成私钥对:{%d, %d}"% (self.__d, self.__n)

    def __gcd_x_y(self, x, y):
        # 求最大公倍数
        if y == 0:
            return x
        else:
            return self.__gcd_x_y(y, x % y)

    @staticmethod
    def __quick_pow_mod(a, b, c):
        # 计算a^b % c, 快速幂算法
        ans = 1  # 记录结果
        a = a % c  # 预处理,使得a处于c的数据范围之下
        while b != 0:
            if b & 1:  # 如果b的二进制位不是0,那么我们的结果是要参与运算的
                ans = (ans * a) % c
            b >>= 1  # 二进制的移位操作,相当于每次除以2,用二进制看,就是我们不断的遍历b的二进制位
            a = (a * a) % c  # 不断的加倍
        return ans

    def __create_key(self):
        prime_list = self.__create_prime_list()
        import random
        # 得到两个素数
        p = prime_list[random.randint(0, len(prime_list)-1)]
        q = prime_list[random.randint(0, len(prime_list) - 1)]
        self.__fanN = (p-1) * (q-1)
        while True:
            self.__e = random.randint(2, self.__fanN)
            if self.__gcd_x_y(self.__e, self.__fanN) == 1:
                break
        for i in range(self.__fanN):
            if i*self.__e % self.__fanN == 1:
                self.__d = i
                break
        self.__n = q * p
        # 得到公钥{e, n} 私钥{d, n}


if __name__ == "__main__":
    rsa = RSA()
    print(rsa.get_public_key())
    print(rsa.get_private_key())
    plain_text = int(input("请输入要加密的明文:"))
    cipher = rsa.rsa_encrypt(plain_text)
    print("%d 经过加密后为:%d" % (plain_text, cipher))
    print("%d 经过解密后为:%d" % (cipher, rsa.rsa_decrypt(cipher)))


结果

自动生成公钥对:{14379305, 47404061}
自动生成私钥对:{46435097, 47404061}
请输入要加密的明文:45617
45617 经过加密后为:26804920
26804920 经过解密后为:45617

Process finished with exit code 0

每次执行的结果不同

说明:

由于本例子只是演示,p,q素数取得比较小,并且是实时生成的素数列表,运行速度比较慢。可以给定一个大素数列表,直接随机抽取素数,速度会更快。

博主是咸鱼,刚刚开始翻身,如果有错误或者建议请指出,不甚感谢
原文地址:https://www.cnblogs.com/jlxa162hhf/p/14161265.html