中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python中的RSA加密與解密實例解析

發布時間:2020-08-20 20:34:17 來源:腳本之家 閱讀:301 作者:lanston 欄目:開發技術

這篇文章主要介紹了python RSA加密與解密實現詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

什么是RSA:

RSA公開密鑰密碼體制。所謂的公開密鑰密碼體制就是使用不同的加密密鑰與解密密鑰,是一種“由已知加密密鑰推導出解密密鑰在計算上是不可行的”密碼體制。

在公開密鑰密碼體制中,加密密鑰(即公開密鑰)PK是公開信息,而解密密鑰(即秘密密鑰)SK是需要保密的。加密算法E和解密算法D也都是公開的。雖然解密密鑰SK是由公開密鑰PK決定的,但卻不能根據PK計算出SK。

正是基于這種理論,1978年出現了著名的RSA算法,它通常是先生成一對RSA 密鑰,其中之一是保密密鑰,由用戶保存;另一個為公開密鑰,可對外公開,甚至可在網絡服務器中注冊。為提高保密強度,RSA密鑰至少為500位長,一般推薦使用1024位。這就使加密的計算量很大。為減少計算量,在傳送信息時,常采用傳統加密方法與公開密鑰加密方法相結合的方式,即信息采用改進的DES或IDEA密鑰加密,然后使用RSA密鑰加密對話密鑰和信息摘要。對方收到信息后,用不同的密鑰解密并可核對信息摘要。

RSA算法是第一個能同時用于加密和數字簽名的算法,也易于理解和操作。RSA是被研究得最廣泛的公鑰算法,從提出到現今的三十多年里,經歷了各種攻擊的考驗,逐漸為人們接受,截止2017年被普遍認為是最優秀的公鑰方案之一。

SET(Secure Electronic Transaction)協議中要求CA采用2048bits長的密鑰,其他實體使用1024比特的密鑰。RSA密鑰長度隨著保密級別提高,增加很快。下表列出了對同一安全級別所對應的密鑰長度。

python實現對RSA的加密和解密

Python密碼庫--Pycrypto

Python良好的生態,對于加密解密技術都有成熟的第三方庫。大名鼎鼎的M2Crypto和Pycrypto,前者非常容易使用,可是安裝卻非常頭疼,不同的系統依賴軟件的版本還有影響。后者則比較方面,直接使用pip安裝即可。

密碼技術

為了進行加密以及通信,人們發明了很多公開的算法。對稱與非對稱算法等。常見的加密方式有RSA, AES等算法。對于選擇加密算法,一個常識就是使用公開的算法。一方面是這些算法經過實踐檢驗,另一方面對于破譯難度和破譯條件破譯時間都有預估。對于任何加密算法,都是能破解的,不同在于時間上的投入。

Python密碼庫--Pycrypto

Python良好的生態,對于加密解密技術都有成熟的第三方庫。大名鼎鼎的M2Crypto和Pycrypto,前者非常容易使用,可是安裝卻非常頭疼,不同的系統依賴軟件的版本還有影響。后者則比較方面,直接使用pip安裝即可。

安裝

pip install pycrypto

RSA 密碼算法與簽名

RSA是一種公鑰密碼算法,RSA的密文是對代碼明文的數字的 E 次方求mod N 的結果。也就是將明文和自己做E次乘法,然后再將其結果除以 N 求余數,余數就是密文。RSA是一個簡潔的加密算法。E 和 N 的組合就是公鑰(public key)。

對于RSA的解密,即密文的數字的 D 次方求mod N 即可,即密文和自己做 D 次乘法,再對結果除以 N 求余數即可得到明文。D 和 N 的組合就是私鑰(private key)。

算法的加密和解密還是很簡單的,可是公鑰和私鑰的生成算法卻不是隨意的。本文在于使用,對生成秘鑰對的算法就暫時忽略。使用 Pycrypto生成秘鑰對很簡單,我們分別為 Server和Client各生成一對屬于自己的秘鑰對。

from Crypto import Random
from Crypto.Hash import SHA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.PublicKey import RSA
 
# 偽隨機數生成器
random_generator = Random.new().read
# rsa算法生成實例
rsa = RSA.generate(1024, random_generator)
 
# Server的秘鑰對的生成
private_pem = rsa.exportKey()
with open("server-private.pem", "w") as f:
 f.write(private_pem)
 
public_pem = rsa.publickey().exportKey()
with open("server-public.pem", "w") as f:
 f.write(public_pem)
 
# Client的秘鑰對的生成
private_pem = rsa.exportKey()
with open("client-private.pem", "w") as f:
 f.write(private_pem)
 
public_pem = rsa.publickey().exportKey()
with open("client-public.pem", "w") as f:
 f.write(public_pem)

所生成的私鑰和公鑰大概是這樣的:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC26X6A0WCWiVxdxq3jtm42yDdGbf+99v2zyi0UMVGZfowlnkcW
eMvpz8NBm2UVlrjZpnFr8wFkdHyjFFkq/ilclH3AN4+Xw8Ap7CGJ2jVMyS5h9RRB
Uyf3F4D5Og8789Ywh9HXYyvD/6J62EtbbkhGPxg3aa8n2kfKZ9N6Q7DqrwIDAQAB
AoGBAJn5qu1D1FxE24Vxl7ZGPzdMigN227+NaPptak9CSR++gLm2KL+JBpcXt5XF
+20WCRvnWjl2QijPSpB5s6pWdHezEa1cl6WrqB1jDJd1U99WNCL5+nfEVD9IF+uE
ig0pnj+wAT5fu78Z0UjxD9307f9S7BLC8ou3dWVkIqob6W95AkEAuPGTNlTkquu/
wBJTb4/+/2ZCf7Ci9qvsN3+RcrzFkKa3uTtBOa6Xk2R61zBkucUgY6cQHPbxhFLN
TVmXdbwxTQJBAP0wGenVOq4dCPdz3NhyghkKT6SL2w/SgbrROiJ1mG9MoBq58/0g
k85I91R7nuvOYTKTUkhWdPYITpDarmPJzesCQGRBmOMgHCHH0NfHV3Gn5rz+61eb
IoyD4Hapceh5CsWCiyAfzhj9229sTecvdbr68Lb0zphVCdIIrQCca63IShUCQGYI
e3jzmHlQdCudArQruWgz8pKiVf7TW7qY1O/MKkk4PRFoPP6WoVoxp5LhWtM20Y7b
Nf628N2xzU+tAThvvE8CQQCI1C7GO3I5EMfqPbTSq2oZq8thvGlyFyI7SNNuvAHj
hj2+0217B9CcTZqloYln01CNDVuaoUgEvFSw1OdRB1tC
-----END RSA PRIVATE KEY-----
 
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC26X6A0WCWiVxdxq3jtm42yDdG
bf+99v2zyi0UMVGZfowlnkcWeMvpz8NBm2UVlrjZpnFr8wFkdHyjFFkq/ilclH3A
N4+Xw8Ap7CGJ2jVMyS5h9RRBUyf3F4D5Og8789Ywh9HXYyvD/6J62EtbbkhGPxg3
aa8n2kfKZ9N6Q7DqrwIDAQAB
-----END PUBLIC KEY-----

加密與解密

通常通信的時候,發送者使用接受者的公鑰加密,接受者使用接受者私鑰解密。

簡而言之,Server給Client通信,需要加密內容,那么Client會生成一個秘鑰對,Client的公鑰client-public.pem和私鑰client-private.pem 。Client把公鑰公開給發送者,任何人都可以用來加密,然后Server使用client-public.pem進行加密,然后把內容發給Client,Client再使用私鑰client-private.pem進行解密。

1.加密(encrypt)

# Server使用Client的公鑰對內容進行rsa 加密
 
message = "hello client, this is a message"
with open("client-public.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  cipher = Cipher_pkcs1_v1_5.new(rsakey)
  cipher_text = base64.b64encode(cipher.encrypt(message.encode('utf-8')))
  print(cipher_text.decode('utf-8'))
 
#加密結果:
HYQPGB+axWCbPp7PPGNTJEAhVPW0TX5ftvUN2v40ChBLB1pS+PVM3YGT5vfcsvmPZhW8NKVSBp8FwjLUnMn6yXP1O36NaunUzyHwI+cpjlkTwZs3DfCY/32EzeuKuJABin1FHBYUMTOKtHy+eEDOuaJTnZTC7ZBkdha+J88HXSc=

cipher_text 即 Master加密后將要發送給Client的密文。

2.解密(decrypt)

# Client使用自己的私鑰對內容進行rsa 解密
 
with open("client-private.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  cipher = Cipher_pkcs1_v1_5.new(rsakey)
  text = cipher.decrypt(base64.b64decode(encrypt_text), random_generator)
  print(text.decode('utf-8'))
 
#解密結果:
hello client, this is a message

這樣Client就能看到Server所發的內容了,當然,如果Client想要給Server發消息,就需要Server先把其的公鑰給Client,后者再使用公鑰加密,然后發送給Server,最后Server使用自己的私鑰解密。

簽名與驗簽

當然,對于竊聽者,有時候也可以對偽造Server給Client發送內容。為此出現了數字簽名。也就是Server給Client發送消息的時候,先對消息進行簽名,表明自己的身份,并且這個簽名無法偽造。具體過程即Server使用自己的私鑰對內容簽名,然后Client使用Server的公鑰進行驗簽。

簽名

# Server使用自己的私鑰對內容進行簽名
 with open("server-private.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  signer = Signature_pkcs1_v1_5.new(rsakey)
  digest = SHA.new()
  digest.update(message)
  sign = signer.sign(digest)
  signature = base64.b64encode(sign)
  print signature
 
#簽名結果:
jVUcAYfgF5Pwlpgrct3IlCX7KezWqNI5tD5OIFTrfCOQgfyCrOkN+/gRLsMiSDOHhFPj2LnfY4Cr5u4eG2IiH8+uSF5z4gUX48AqCQlqiOTLk2EGvyp+w+iYo2Bso1MUi424Ebkx7SnuJwLiPqNzIBLfEZLA3ov69aDArh7hQiw=

驗簽

#Client使用Server的公鑰對內容進行驗簽
 
with open("server-public.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  verifier = Signature_pkcs1_v1_5.new(rsakey)
  digest = SHA.new()
  # Assumes the data is base64 encoded to begin with
  digest.update(message)
  is_verify = signer.verify(digest, base64.b64decode(signature))
  print is_verify
#驗簽結果:
True

總結

Pycrypto提供了比較完善的加密算法。RSA廣泛用于加密與解密,還有數字簽名通信領域。使用Publick/Private秘鑰算法中,加密主要用對方的公鑰,解密用自己的私鑰。簽名用自己的私鑰,驗簽用對方的公鑰。

  • 加密解密:公鑰加密,私鑰解密
  • 簽名驗簽:私鑰簽名,公鑰驗簽

無論是加密解密還是簽名驗簽都使用同一對秘鑰對。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平塘县| 包头市| 奉化市| 中江县| 云安县| 龙岩市| 甘谷县| 怀远县| 体育| 湖北省| 阿城市| 洱源县| 原平市| 绥江县| 牙克石市| 茂名市| 玛沁县| 邳州市| 东至县| 新建县| 封丘县| 繁昌县| 饶河县| 根河市| 张家川| 马公市| 金川县| 万盛区| 姜堰市| 皋兰县| 灵武市| 临沂市| 托克逊县| 新和县| 寿光市| 许昌县| 高阳县| 平顶山市| 卓尼县| 文成县| 虞城县|