25行代码实现完整的RSA算法


声明:本文转载自https://my.oschina.net/KFeC5dSwgN1q/blog/1623311,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

插播一条广告→2021 ByteDance字节跳动内推←各城市、各方向的岗位都有,大量招人!


25行代码实现完整的RSA算法

<p>网络上很多关于RSA算法的原理介绍,可就是没有一个靠谱的算法实现,即使有代码介绍,也都是直接调用JDK或者Python代码包中的API实现,所以只可远观而不可亵玩已。本屌丝用了2天时间把RSA算法的代码完全实现了一遍以后发现代码竟然这么少,25行就全部搞定。为了方便整数的计算,我使用了Python语言。为什么用Python?因为Java语言需要用到BigInteger类,数值的计算都是用方法调用,所以使用起来比较麻烦。如果有同学对我得代码感兴趣的话,先二话不说,不管3X7=22,把代码粘贴进pydev中运行一遍,是驴是马拉出来溜溜。然后私信我,我就把代码具体讲讲,如果本文章没有人感兴趣,我就不做讲解了。 <p>代码主要涉及到三个Python文件,计算最大公约数、大整数幂取模算法、公钥私钥生成。这三个文件构成了RSA算法的核心。 <p>前方高能,我要开始装逼了。只有代码,看不懂的童鞋请绕道,先去看看理论,具体内容如下:

  1. 计算最大公约数
  2. 超大整数的超大整数次幂取超大整数模算法(好拗口,哈哈,不拗口一点就显示不出这个算法的超级牛逼之处)
  3. 公钥私钥生成

计算最大公约数与扩展欧几里得算法

gcd.py文件,gcd方法用来计算两个整数的最大公约数。ext_gcd是扩展欧几里得方法的计算公式。

# -*- coding: utf-8 -*-  # 求两个数字的最大公约数(欧几里得算法) def gcd(a, b):     if b == 0:         return a     else:         return gcd(b, a % b)  ''' 扩展欧几里的算法 计算 ax + by = 1中的x与y的整数解 ''' 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 

大整数幂取模算法

exponentiation.py文件,主要用于计算超大整数超大次幂然后对超大的整数取模。

# -*- coding: utf-8 -*-  ''' 超大整数超大次幂然后对超大的整数取模 (base ^ exponent) mod n ''' 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)     return a_w_b % n  def __multi(array, bin_array):     result = 1     for index in range(len(array)):         a = array[index]         if not int(bin_array[index]):             continue         result *= a     return result 

有同学就不服了,说是我为啥不把这个幂次的数字计算出来,再取模。我说这样做,理论上是对的,但是实际上行不通。因为:一个2048位的数字的2048位次的幂,计算出来了以后,这个数字很可能把全宇宙的物质都做成硬盘也放不下。不懂的童鞋请私信我掰扯掰扯。所以需要用优化后的方法进行计算。

公钥私钥生成

rsa.py,生成公钥、私钥、并对信息加密解密。

# -*- coding: utf-8 -*- from gcd import ext_gcd from exponentiation import exp_mode  # 生成公钥私钥,p、q为两个超大质数 def gen_key(p, q):     n = p * q     fy = (p - 1) * (q - 1)      # 计算与n互质的整数个数     e = 3889                    # 选取e     # generate d     a = e     b = fy     r, x, y = ext_gcd(a, b)     print x   # 计算出的x不能是负数,如果是负数,说明p、q、e选取失败,一般情况下e选取65537     d = x     # 返回:   公钥     私钥     return    (n, e), (n, d)      # 加密 def encode(m, pubkey):     n = pubkey[0]     e = pubkey[1]          c = exp_mode(m, e, n)     return c  解密 def decode(c, selfkey):     n = selfkey[0]     d = selfkey[1]          m = exp_mode(c, d, n)     return m           if __name__ == "__main__":     '''公钥私钥中用到的两个大质数p,q'''     p = 106697219132480173106064317148705638676529121742557567770857687729397446898790451577487723991083173010242416863238099716044775658681981821407922722052778958942891831033512463262741053961681512908218003840408526915629689432111480588966800949428079015682624591636010678691927285321708935076221951173426894836169     q = 144819424465842307806353672547344125290716753535239658417883828941232509622838692761917211806963011168822281666033695157426515864265527046213326145174398018859056439431422867957079149967592078894410082695714160599647180947207504108618794637872261572262805565517756922288320779308895819726074229154002310375209     '''生成公钥私钥'''     pubkey, selfkey = gen_key(p, q)     '''需要被加密的信息'''     m = 1356205320457610288745198967657644166379972189839804389074591563666634066646564410685955217825048626066190866536592405966964024022236587593447122392540038493893121248948780525117822889230574978651418075403357439692743398250207060920929117606033490559159560987768768324823011579283223392964454439904542675637683985296529882973798752471233683249209762843835985174607047556306705224118165162905676610067022517682197138138621344578050034245933990790845007906416093198845798901781830868021761765904777531676765131379495584915533823288125255520904108500256867069512326595285549579378834222350197662163243932424184772115345     '''信息加密'''     c = encode(m, pubkey)     print c     '''信息解密'''     d = decode(c, selfkey)     print d 

代码就是这么简单,RSA算法就是这么任性。代码去除掉没用的注释或者引用,总长度不会超过25行,有疑问的找我掰扯掰扯。本屌丝从不说大话。 实测:秘钥长度在2048位的时候,我的thinkpad笔记本T440上面、python2.7环境的运行时间是4秒,1024位的时候是1秒。如果环境不正确,导致运算出错,自己找原因。 最后,觉得代码写得好的,请给我打赏,支付宝微信:18201637201。

本文发表于2018年02月25日 10:31
(c)注:本文转载自https://my.oschina.net/KFeC5dSwgN1q/blog/1623311,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 860 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1