zoukankan      html  css  js  c++  java
  • 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素数取得比较小,并且是实时生成的素数列表,运行速度比较慢。可以给定一个大素数列表,直接随机抽取素数,速度会更快。

    博主是咸鱼,刚刚开始翻身,如果有错误或者建议请指出,不甚感谢
  • 相关阅读:
    设计模式之单例模式(Singleton)
    ASP.Net WebForm温故知新学习笔记:二、ViewState与UpdatePanel探秘
    ASP.Net WebForm温故知新学习笔记:一、aspx与服务器控件探秘
    [学习笔记] $Maximum$ $Minimum$ $identity$
    BZOJ 2159: Crash 的文明世界(组合数学+第二类斯特林数+树形dp)
    BZOJ 3083: 遥远的国度 (树剖+线段树)
    LUOGU P4560 [IOI2014]Wall 砖墙 (线段树)
    牛客网 NOIP赛前集训营-普及组(第四场)C--部分和 (高维前缀和)
    LUOGU P1501 [国家集训队]Tree II (lct)
    LUOGU P3690 【模板】Link Cut Tree (lct)
  • 原文地址:https://www.cnblogs.com/jlxa162hhf/p/14161265.html
Copyright © 2011-2022 走看看