Python 25行代碼實(shí)現(xiàn)的RSA算法詳解
本文實(shí)例講述了Python 25行代碼實(shí)現(xiàn)的RSA算法。分享給大家供大家參考,具體如下:
網(wǎng)絡(luò)上很多關(guān)于RSA算法的原理介紹,但是翻來(lái)翻去就是沒有一個(gè)靠譜的算法實(shí)現(xiàn),即使有代碼介紹,也都是直接調(diào)用JDK或者Python代碼包中的API實(shí)現(xiàn),或者即使有代碼也都寫得特別爛。無(wú)形中讓人感覺RSA加密算法竟然這么高深,然后就看不下去了。還有我發(fā)現(xiàn)對(duì)于“大整數(shù)的冪次乘方取模”竟然采用直接計(jì)算的冪次的值,再取模,類似于(2 ^ 1024) ^ (2 ^ 1024),這樣的計(jì)算就直接去計(jì)算了,我不知道各位博主有沒有運(yùn)行他們的代碼???知道這個(gè)數(shù)字有多大嗎?這么說(shuō)吧,把全宇宙中的物質(zhì)都做成硬盤都放不下,更何況你的512內(nèi)存的電腦。所以我說(shuō)他們的代碼只可遠(yuǎn)觀而不可褻玩已。
于是我用了2天時(shí)間,沒有去參考網(wǎng)上的代碼重新開始把RSA算法的代碼完全實(shí)現(xiàn)了一遍以后發(fā)現(xiàn)代碼竟然這么少,25行就全部搞定。為了方便整數(shù)的計(jì)算,我使用了Python語(yǔ)言。為什么用Python?因?yàn)镻ython在數(shù)值計(jì)算上比較直觀,而Java語(yǔ)言需要用到BigInteger類,數(shù)值的計(jì)算都是用方法調(diào)用,所以使用起來(lái)比較麻煩。如果有同學(xué)對(duì)我得代碼感興趣的話,先二話不說(shuō),不管3X7=22,把代碼粘貼進(jìn)pydev中運(yùn)行一遍,是驢是馬拉出來(lái)溜溜??床欢梢运叫盼?,我就把代碼具體講講,如果本文章沒有人感興趣,我就不做講解了。
RSA算法的步驟主要有以下幾個(gè)步驟:
①、選擇 p、q兩個(gè)超級(jí)大的質(zhì)數(shù)
②、令n = p * q。取 φ(n) =(p-1) * (q-1)。
③、取 e ∈ 1 < e < φ(n) ,( n , e )為公鑰對(duì)
④、令 ed mod φ(n) = 1,取得d,( n , d ) 為私鑰對(duì)。 利用擴(kuò)展歐幾里的算法進(jìn)行計(jì)算。
⑤、銷毀 p、q。密文 = 明文 ^ e mod n , 明文 = 密文 ^ d mod n。利用蒙哥馬利方法進(jìn)行計(jì)算
代碼主要涉及到三個(gè)Python可執(zhí)行文件:計(jì)算最大公約數(shù)、大整數(shù)冪取模算法、公鑰私鑰生成及加解密。這三個(gè)文件構(gòu)成了RSA算法的核心。
前方高能,我要開始裝逼了??床欢耐?qǐng)繞道,先去看看理論,具體內(nèi)容如下:
1. 計(jì)算最大公約數(shù)
2. 超大整數(shù)的超大整數(shù)次冪取超大整數(shù)模算法(好拗口,哈哈,不拗口一點(diǎn)就顯示不出這個(gè)算法的超級(jí)牛逼之處)
3. 公鑰私鑰生成
1、計(jì)算最大公約數(shù)與擴(kuò)展歐幾里得算法
gcd.py文件,gcd方法用來(lái)計(jì)算兩個(gè)整數(shù)的最大公約數(shù)。ext_gcd是擴(kuò)展歐幾里得方法的計(jì)算公式。
# -*- coding: utf-8 -*- # 求兩個(gè)數(shù)字的最大公約數(shù)(歐幾里得算法) def gcd(a, b): if b == 0: return a else: return gcd(b, a % b) ''' 擴(kuò)展歐幾里的算法 計(jì)算 ax + by = 1中的x與y的整數(shù)解(a與b互質(zhì)) ''' 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
2、大整數(shù)冪取模算法
exponentiation.py文件,主要用于計(jì)算超大整數(shù)超大次冪然后對(duì)超大的整數(shù)取模。我在網(wǎng)上查詢到這個(gè)算法叫做“蒙哥馬利算法”。
# -*- coding: utf-8 -*- ''' 超大整數(shù)超大次冪然后對(duì)超大的整數(shù)取模 (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
有同學(xué)就不服了,說(shuō)是我為啥不把這個(gè)冪次的數(shù)字計(jì)算出來(lái),再取模。我說(shuō)這樣做,理論上是對(duì)的,但是實(shí)際上行不通。因?yàn)椋阂粋€(gè)2048位的數(shù)字的2048位次的冪,計(jì)算出來(lái)了以后,這個(gè)數(shù)字很可能把全宇宙的物質(zhì)都做成硬盤也放不下。不懂的童鞋請(qǐng)私信我。所以需要用“蒙哥馬利算法”進(jìn)行優(yōu)化。
3、公鑰私鑰生成
rsa.py,生成公鑰、私鑰、并對(duì)信息加密解密。
# -*- coding: utf-8 -*- from gcd import ext_gcd from exponentiation import exp_mode # 生成公鑰私鑰,p、q為兩個(gè)超大質(zhì)數(shù) def gen_key(p, q): n = p * q fy = (p - 1) * (q - 1) # 計(jì)算與n互質(zhì)的整數(shù)個(gè)數(shù) 歐拉函數(shù) e = 3889 # 選取e 一般選取65537 # generate d a = e b = fy r, x, y = ext_gcd(a, b) print x # 計(jì)算出的x不能是負(fù)數(shù),如果是負(fù)數(shù),說(shuō)明p、q、e選取失敗,一般情況下e選取65537 d = x # 返回: 公鑰 私鑰 return (n, e), (n, d) # 加密 m是被加密的信息 加密成為c def encrypt(m, pubkey): n = pubkey[0] e = pubkey[1] c = exp_mode(m, e, n) return c # 解密 c是密文,解密為明文m def decrypt(c, selfkey): n = selfkey[0] d = selfkey[1] m = exp_mode(c, d, n) return m if __name__ == "__main__": '''公鑰私鑰中用到的兩個(gè)大質(zhì)數(shù)p,q''' p = 106697219132480173106064317148705638676529121742557567770857687729397446898790451577487723991083173010242416863238099716044775658681981821407922722052778958942891831033512463262741053961681512908218003840408526915629689432111480588966800949428079015682624591636010678691927285321708935076221951173426894836169 q = 144819424465842307806353672547344125290716753535239658417883828941232509622838692761917211806963011168822281666033695157426515864265527046213326145174398018859056439431422867957079149967592078894410082695714160599647180947207504108618794637872261572262805565517756922288320779308895819726074229154002310375209 '''生成公鑰私鑰''' pubkey, selfkey = gen_key(p, q) '''需要被加密的信息轉(zhuǎn)化成數(shù)字,長(zhǎng)度小于秘鑰n的長(zhǎng)度,如果信息長(zhǎng)度大于n的長(zhǎng)度,那么分段進(jìn)行加密,分段解密即可。''' m = 1356205320457610288745198967657644166379972189839804389074591563666634066646564410685955217825048626066190866536592405966964024022236587593447122392540038493893121248948780525117822889230574978651418075403357439692743398250207060920929117606033490559159560987768768324823011579283223392964454439904542675637683985296529882973798752471233683249209762843835985174607047556306705224118165162905676610067022517682197138138621344578050034245933990790845007906416093198845798901781830868021761765904777531676765131379495584915533823288125255520904108500256867069512326595285549579378834222350197662163243932424184772115345 '''信息加密''' c = encrypt(m, pubkey) print c '''信息解密''' d = decrypt(c, selfkey) print d
代碼就是這么簡(jiǎn)單,RSA算法就是這么任性。代碼去除掉沒用的注釋或者引用,總長(zhǎng)度不會(huì)超過(guò)25行,有疑問(wèn)的我們掰扯掰扯。
實(shí)測(cè):秘鑰長(zhǎng)度在2048位的時(shí)候,我的thinkpad筆記本T440上面、python2.7環(huán)境的運(yùn)行時(shí)間是4秒,1024位的時(shí)候是1秒。說(shuō)明了RSA加密算法的算法復(fù)雜度應(yīng)該是O(N^2),其中n是秘鑰長(zhǎng)度。不知道能不能優(yōu)化到O(NlogN)
PS:關(guān)于加密解密感興趣的朋友還可以參考本站在線工具:
在線RSA加密/解密工具:
http://tools.jb51.net/password/rsa_encode
文字在線加密解密工具(包含AES、DES、RC4等):
http://tools.jb51.net/password/txt_encode
MD5在線加密工具:
http://tools.jb51.net/password/CreateMD5Password
在線散列/哈希算法加密工具:
http://tools.jb51.net/password/hash_encrypt
在線MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密工具:
http://tools.jb51.net/password/hash_md5_sha
在線sha1/sha224/sha256/sha384/sha512加密工具:
http://tools.jb51.net/password/sha_encode
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python加密解密算法與技巧總結(jié)》、《Python編碼操作技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》及《Python入門與進(jìn)階經(jīng)典教程》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
- python中的RSA加密與解密實(shí)例解析
- python rsa實(shí)現(xiàn)數(shù)據(jù)加密和解密、簽名加密和驗(yàn)簽功能
- Flask框架實(shí)現(xiàn)的前端RSA加密與后端Python解密功能詳解
- Python生成rsa密鑰對(duì)操作示例
- python實(shí)現(xiàn)AES和RSA加解密的方法
- Python下實(shí)現(xiàn)的RSA加密/解密及簽名/驗(yàn)證功能示例
- Python使用Pycrypto庫(kù)進(jìn)行RSA加密的方法詳解
- Python如何基于rsa模塊實(shí)現(xiàn)非對(duì)稱加密與解密
相關(guān)文章
pydev debugger: process 10341 is co
這篇文章主要介紹了pydev debugger: process 10341 is connecting無(wú)法debu的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04一文搞懂Pandas數(shù)據(jù)透視的4個(gè)函數(shù)的使用
今天主要和大家分享Pandas中四種有關(guān)數(shù)據(jù)透視的通用函數(shù),在數(shù)據(jù)處理中遇到這類需求時(shí),能夠很好地應(yīng)對(duì),快跟隨小編一起學(xué)習(xí)一下吧2022-06-06利用Python實(shí)現(xiàn)自動(dòng)掃雷小腳本
這篇文章主要介紹了利用Python實(shí)現(xiàn)自動(dòng)掃雷小腳本,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Python實(shí)現(xiàn)的RSS閱讀器實(shí)例
這篇文章主要介紹了Python實(shí)現(xiàn)的RSS閱讀器,實(shí)例分析了XML解析實(shí)現(xiàn)RSS閱讀的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07pycharm如何設(shè)置自動(dòng)生成作者信息
這篇文章主要介紹了pycharm如何設(shè)置自動(dòng)生成作者信息,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02Python?subprocess.Popen?實(shí)時(shí)輸出?stdout的解決方法(正確管道寫法)
這篇文章主要介紹了Python?subprocess.Popen實(shí)時(shí)輸出stdout正確管道寫法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07