Python中Cryptography庫(kù)實(shí)現(xiàn)加密解密
先介紹與加密解密有關(guān)的幾個(gè)基本概念。
- 加密(Encryption):加密是將明文轉(zhuǎn)換為密文的過(guò)程,使得未經(jīng)授權(quán)的人無(wú)法讀懂。
- 解密(Decryption):解密是將密文轉(zhuǎn)換為明文的過(guò)程,使得原始信息可以被正確的人閱讀。
- 密鑰(Key):密鑰是加密和解密過(guò)程中的關(guān)鍵。它可以是單個(gè)數(shù)字、字符串或者是更復(fù)雜的密鑰對(duì)象。
- 算法:算法是加密和解密過(guò)程中的具體步驟。
cryptography是一個(gè)強(qiáng)大的Python庫(kù),提供了一套豐富的加密相關(guān)的操作,用于安全地處理數(shù)據(jù)。它旨在提供簡(jiǎn)單易用的加密方法,同時(shí)也支持更高級(jí)的加密需求,使這項(xiàng)技術(shù)變得易于使用。cryptography庫(kù)包含兩個(gè)主要的高級(jí)組件:Fernet(對(duì)稱加密)和hazmat(危險(xiǎn)材料層)。
主要特點(diǎn)
- 易用性:cryptography庫(kù)的設(shè)計(jì)初衷是易于使用,盡量減少安全漏洞的出現(xiàn)。
- 安全性:它提供了最新的加密算法,并且經(jīng)過(guò)安全專家的審查。
- 靈活性:對(duì)于需要直接訪問(wèn)加密算法的高級(jí)用戶,cryptography提供了hazmat模塊。
主要組件
Fernet:提供了對(duì)稱加密的實(shí)現(xiàn),非常適合用于加密和解密可以安全共享密鑰的場(chǎng)景。使用Fernet非常簡(jiǎn)單,只需要一個(gè)密鑰就可以進(jìn)行安全的數(shù)據(jù)加密和解密。
hazmat(Hazardous Materials):這個(gè)模塊提供了底層加密原語(yǔ)(如塊密碼、消息摘要算法等)。它是為那些需要執(zhí)行特定加密操作的高級(jí)用戶設(shè)計(jì)的,但使用時(shí)需要格外小心,因?yàn)椴划?dāng)?shù)氖褂每赡軐?dǎo)致安全問(wèn)題。
官方文檔https://cryptography.io/en/latest/
在Windows平臺(tái)上安裝cryptography,可在cmd命令行中,輸入如下命令:
pip install cryptography
回車,默認(rèn)情況使用國(guó)外線路較慢,我們可以使用國(guó)內(nèi)的鏡像網(wǎng)站:
豆瓣:https://pypi.doubanio.com/simple/
清華:https://pypi.tuna.tsinghua.edu.cn/simple
電腦上安裝了多個(gè)Python版本,你可以為特定版本的Python安裝模塊(庫(kù)、包)。例如我的電腦中安裝了多個(gè)Python版本,要在Python 3.10版本中安裝,并使用清華的鏡像,cmd命令行中,輸入如下命令
py -3.10 -m pip install cryptography -i https://pypi.tuna.tsinghua.edu.cn/simple
示例
1、生成私鑰和獲取公鑰
# -*- coding: utf-8 -*- from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa # 生成私鑰 private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) # 獲取公鑰 public_key = private_key.public_key()
2、私鑰和公鑰序列化
# 私鑰序列化 private_key_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) # 保存私鑰到文件 with open('private.key', 'wb') as f: f.write(private_key_pem) # 公鑰序列化 public_key_pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) # 保存公鑰到文件 with open('public.pem', 'wb') as f: f.write(public_key_pem)
3、私鑰和公鑰的反序列化
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization # 從文件加載私鑰 with open("private.key", "rb") as private_key_file: private_key = serialization.load_pem_private_key( private_key_file.read(), password=None, backend=default_backend() ) # 從文件加載公鑰 with open("public.pem", "rb") as public_pem_file: public_key = serialization.load_pem_public_key( public_pem_file.read(), backend=default_backend() )
4、公鑰加密私鑰解密
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding # 公鑰解密 message = 'Hello' encrypted = public_key.encrypt( plaintext=message.encode('utf-8'), padding=padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print(encrypted) # b'm\xf2\x8d\xa84\xbe\x13\xe1...' # 私鑰解密 original_message = private_key.decrypt( ciphertext=encrypted, padding=padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print(original_message.decode('utf-8')) # Hello
5、私鑰簽名公鑰驗(yàn)簽
# -*- coding: utf-8 -*- from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding # 私鑰簽名 message = 'Hello' signature = private_key.sign( data=message.encode('utf-8'), padding=padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), algorithm=hashes.SHA256() ) print(signature) # b'm\xf2\x8d\xa84\xbe\x13\xe1...' # 公鑰驗(yàn)簽 如果驗(yàn)證失敗拋出異常cryptography.exceptions.InvalidSignature public_key.verify( signature=signature, data='Hello'.encode('utf-8'), padding=padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), algorithm=hashes.SHA256() )
簡(jiǎn)單示例:使用Fernet進(jìn)行數(shù)據(jù)加密和解密源碼:
from cryptography.fernet import Fernet # 生成密鑰 key = Fernet.generate_key() cipher_suite = Fernet(key) # 加密數(shù)據(jù) data = b"Hello, cryptography!" encrypted_data = cipher_suite.encrypt(data) print(f"Encrypted: {encrypted_data}") # 解密數(shù)據(jù) decrypted_data = cipher_suite.decrypt(encrypted_data) print(f"Decrypted: {decrypted_data}")
運(yùn)行效果:
圖形用戶界面的文件加密解密程序
使用tkinter添加界面的加密解密程序,當(dāng)用戶點(diǎn)擊“加密文件”或“解密文件”按鈕時(shí),程序會(huì)從這個(gè)文本框中獲取密鑰,并使用它進(jìn)行相應(yīng)的加密或解密操作。加密和解密的文件將會(huì)被保存在與原文件相同的目錄下,加密文件的文件名在原圖片文件名前添加enc_,解密文件的文件名在原加密圖片文件名前添加dec_
先給出運(yùn)行效果:
源碼如下:
import tkinter as tk from tkinter import filedialog from cryptography.fernet import Fernet import os def encrypt(filename, key, status_label): try: f = Fernet(key.encode()) # 將密鑰從字符串轉(zhuǎn)換為字節(jié) with open(filename, "rb") as file: file_data = file.read() encrypted_data = f.encrypt(file_data) dir_name, base_filename = os.path.split(filename) # 分離目錄和文件名 encrypted_filename = f"enc_{base_filename}" # 將加密文件保存在原始目錄中 encrypted_file_path = os.path.join(dir_name, encrypted_filename) with open(encrypted_file_path, "wb") as file: file.write(encrypted_data) status_label.config(text=f"提示:文件已加密:{encrypted_filename}") except Exception as e: status_label.config(text=f"提示:加密失敗: {str(e)}") def decrypt(filename, key, status_label): try: f = Fernet(key.encode()) # 將密鑰從字符串轉(zhuǎn)換為字節(jié) with open(filename, "rb") as file: encrypted_data = file.read() decrypted_data = f.decrypt(encrypted_data) # 分離目錄和文件名 dir_name, base_filename = os.path.split(filename) decrypted_filename = f"dec_{base_filename}" # 將解密文件保存在原始目錄中 decrypted_file_path = os.path.join(dir_name, decrypted_filename) with open(decrypted_file_path, "wb") as file: file.write(decrypted_data) status_label.config(text=f"提示:文件已解密:{decrypted_filename}") except Exception as e: status_label.config(text=f"提示:解密失敗: {str(e)}") # 創(chuàng)建GUI界面 def select_file(operation, key_entry, status_label): key = key_entry.get() # 從文本框獲取密鑰 if not key: status_label.config(text="提示:操作失敗:未輸入密鑰") return file_path = filedialog.askopenfilename() if file_path: # 如果file_path不是空字符串 if operation == 'encrypt': encrypt(file_path, key, status_label) elif operation == 'decrypt': decrypt(file_path, key, status_label) else: status_label.config(text="提示:沒(méi)有選擇文件") def main(): root = tk.Tk() root.title("加密解密程序") tk.Label(root, text="密鑰:").pack() key_entry = tk.Entry(root, show='*', width=50) # 密鑰輸入框 key_entry.insert(0, 'X3Q8PvDs2EzKHK-8TjgUE8HkZ8QeuOe0S7-3VVqjTDI=') # 設(shè)置默認(rèn)值 key_entry.pack() status_label = tk.Label(root, text="提示:請(qǐng)選擇操作", height=2) status_label.pack() tk.Button(root, text="加密文件", command=lambda: select_file('encrypt', key_entry, status_label)).pack() tk.Button(root, text="解密文件", command=lambda: select_file('decrypt', key_entry, status_label)).pack() root.mainloop() if __name__ == "__main__": main()
cryptography庫(kù)提供了許多高級(jí)功能,提供了多種密碼學(xué)算法,包括對(duì)稱加密、非對(duì)稱加密、哈希函數(shù)、簽名、密鑰管理等等。支持多種加密標(biāo)準(zhǔn),包括AES、DES、RSA、SSL/TLS等等,同時(shí)也提供了許多密碼學(xué)工具,如密碼學(xué)隨機(jī)數(shù)生成器、PBKDF2函數(shù)、密碼學(xué)算法器等等。關(guān)于這些詳情請(qǐng)閱讀相關(guān)文檔,在此僅舉以下是一個(gè)簡(jiǎn)單的例子,展示了如何生成RSA密鑰對(duì)、使用公鑰進(jìn)行加密以及使用私鑰進(jìn)行解密,源碼如下:
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import hashes # 生成RSA密鑰對(duì) private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) public_key = private_key.public_key() # 將私鑰序列化并保存到文件 with open("private_key.pem", "wb") as f: f.write(private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() )) # 將公鑰序列化并保存到文件 with open("public_key.pem", "wb") as f: f.write(public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo )) # 讀取公鑰進(jìn)行加密 with open("public_key.pem", "rb") as f: public_key = serialization.load_pem_public_key( f.read(), backend=default_backend() ) message = "Hello, RSA Cryptography!".encode() encrypted = public_key.encrypt( message, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) # 讀取私鑰進(jìn)行解密 with open("private_key.pem", "rb") as f: private_key = serialization.load_pem_private_key( f.read(), password=None, backend=default_backend() ) original_message = private_key.decrypt( encrypted, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) # 顯示解密后的消息 print(original_message.decode())
這個(gè)例子首先生成了一個(gè)2048位的RSA密鑰對(duì),將私鑰保存到private_key.pem文件中,將公鑰保存到public_key.pem文件中。接下來(lái),代碼從public_key.pem文件中讀取公鑰用于加密消息,從private_key.pem文件中讀取私鑰用于解密消息。最后,使用公鑰對(duì)一段消息進(jìn)行加密,然后使用私鑰將消息解密。padding.OAEP是一種常用的填充方式,與SHA-256哈希算法一起使用,以確保加密過(guò)程的安全性。
到此這篇關(guān)于Python中Cryptography庫(kù)實(shí)現(xiàn)加密解密的文章就介紹到這了,更多相關(guān)Python Cryptography加密解密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python光學(xué)仿真理解Jones矩陣學(xué)習(xí)
這篇文章主要為大家介紹了Python光學(xué)仿真理解Jones矩陣的學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2021-10-10python matplotlib imshow熱圖坐標(biāo)替換/映射實(shí)例
這篇文章主要介紹了python matplotlib imshow熱圖坐標(biāo)替換/映射實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03python實(shí)現(xiàn)自動(dòng)登錄12306自動(dòng)搶票功能
隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,越來(lái)越多的人選擇通過(guò)網(wǎng)絡(luò)平臺(tái)購(gòu)票,特別是在中國(guó),12306作為官方火車票預(yù)訂平臺(tái),承擔(dān)了巨大的訪問(wèn)量,對(duì)于熱門(mén)線路或者節(jié)假日出行,往往會(huì)出現(xiàn)一票難求的情況,因此,一些技術(shù)愛(ài)好者嘗試?yán)镁幊陶Z(yǔ)言如Python來(lái)開(kāi)發(fā)搶票腳本2025-01-01Python實(shí)現(xiàn)接口自動(dòng)化測(cè)試的方法詳解
Python接口自動(dòng)化測(cè)試是一種高效、可重復(fù)的軟件質(zhì)量驗(yàn)證方法,尤其在現(xiàn)代軟件開(kāi)發(fā)中,它已經(jīng)成為不可或缺的一部分,本文將深入探討如何使用Python進(jìn)行接口自動(dòng)化測(cè)試,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-08-08Python 關(guān)于模塊和加載模塊的實(shí)現(xiàn)
這篇文章主要介紹了Python 關(guān)于模塊和加載模塊的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03python算法與數(shù)據(jù)結(jié)構(gòu)朋友圈與水杯實(shí)驗(yàn)題分析實(shí)例
這篇文章主要介紹了python算法與數(shù)據(jù)結(jié)構(gòu)朋友圈與水杯實(shí)驗(yàn)題分析,總的來(lái)說(shuō)這并不是難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過(guò)程。希望通過(guò)這道題能給你帶來(lái)一種解題優(yōu)化的思路2022-12-12python2.7 json 轉(zhuǎn)換日期的處理的示例
這篇文章主要介紹了python2.7 json 轉(zhuǎn)換日期的處理的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03