溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python如何實(shí)現(xiàn)RSA算法

發(fā)布時(shí)間:2021-08-06 14:23:43 來(lái)源:億速云 閱讀:439 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要為大家展示了“Python如何實(shí)現(xiàn)RSA算法”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Python如何實(shí)現(xiàn)RSA算法”這篇文章吧。

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算法就是這么任性。代碼去除掉沒(méi)用的注釋或者引用,總長(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)

以上是“Python如何實(shí)現(xiàn)RSA算法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI