您好,登錄后才能下訂單哦!
這篇文章主要介紹了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秘鑰算法中,加密主要用對方的公鑰,解密用自己的私鑰。簽名用自己的私鑰,驗簽用對方的公鑰。
無論是加密解密還是簽名驗簽都使用同一對秘鑰對。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。