您好,登錄后才能下訂單哦!
這篇文章主要介紹了Python3常見加密計數方法有哪些的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Python3常見加密計數方法有哪些文章都會有所收獲,下面我們一起來看看吧。
Python 3 的標準庫中沒多少用來解決加密的,不過卻有用于處理哈希的庫。在這里我們會對其進行一個簡單的介紹,但重點會放在兩個第三方的軟件包:PyCrypto 和 cryptography 上。
如果需要用到安全哈希算法或是消息摘要算法,那么你可以使用標準庫中的 hashlib 模塊。這個模塊包含了符合 FIPS(美國聯邦信息處理標準)的安全哈希算法,包括 SHA1,SHA224,SHA256,SHA384,SHA512 以及 RSA 的 MD5 算法。Python 也支持 adler32 以及 crc32 哈希函數,不過它們在 zlib 模塊中。
哈希的一個最常見的用法是,存儲密碼的哈希值而非密碼本身。當然了,使用的哈希函數需要穩健一點,否則容易被破解。另一個常見的用法是,計算一個文件的哈希值,然后將這個文件和它的哈希值分別發送。接收到文件的人可以計算文件的哈希值,檢驗是否與接受到的哈希值相符。如果兩者相符,就說明文件在傳送的過程中未經篡改。
讓我們試著創建一個 md5 哈希:
>>> import hashlib >>> md5 = hashlib.md5() >>> md5.update('Python rocks!') Traceback (most recent call last): File "", line 1, in md5.update('Python rocks!') TypeError: Unicode-objects must be encoded before hashing >>> md5.update(b'Python rocks!') >>> md5.digest() b'/x14/x82/xec/x1b#d/xf6N}/x16*+[/x16/xf4w'
讓我們花點時間一行一行來講解。首先,我們導入 hashlib ,然后創建一個 md5 哈希對象的實例。接著,我們向這個實例中添加一個字符串后,卻得到了報錯信息。原來,計算 md5 哈希時,需要使用字節形式的字符串而非普通字符串。正確添加字符串后,我們調用它的 digest 函數來得到哈希值。如果你想要十六進制的哈希值,也可以用以下方法:
>>> md5.hexdigest()'1482ec1b2364f64e7d162a2b5b16f477'
實際上,有一種精簡的方法來創建哈希,下面我們看一下用這種方法創建一個 sha1 哈希:
>>> sha = hashlib.sha1(b'Hello Python').hexdigest() >>> sha'422fbfbc67fe17c86642c5eaaa48f8b670cbed1b'
可以看到,我們可以同時創建一個哈希實例并且調用其 digest 函數。然后,我們打印出這個哈希值看一下。這里我使用 sha1 哈希函數作為例子,但它不是特別安全,讀者可以隨意嘗試其他的哈希函數。
Python 的標準庫對密鑰導出支持較弱。實際上,hashlib 函數庫提供的唯一方法就是 pbkdf2_hmac 函數。它是 PKCS#5 的基于口令的第二個密鑰導出函數,并使用 HMAC 作為偽隨機函數。因為它支持“加鹽”和迭代操作,你可以使用類似的方法來哈希你的密碼。例如,如果你打算使用 SHA-256 加密方法,你將需要至少 16 個字節的“鹽”,以及最少 100000 次的迭代操作。
簡單來說,“鹽”就是隨機的數據,被用來加入到哈希的過程中,以加大破解的難度。這基本可以保護你的密碼免受字典和彩虹表的攻擊。
讓我們看一個簡單的例子:
>>> import binascii >>> dk = hashlib.pbkdf2_hmac(hash_name='sha256', password=b'bad_password34', salt=b'bad_salt', iterations=100000) >>> binascii.hexlify(dk) b'6e97bad21f6200f9087036a71e7ca9fa01a59e1d697f7e0284cd7f9b897d7c02'
這里,我們用 SHA256 對一個密碼進行哈希,使用了一個糟糕的鹽,但經過了 100000 次迭代操作。當然,SHA 實際上并不被推薦用來創建密碼的密鑰。你應該使用類似 scrypt 的算法來替代。另一個不錯的選擇是使用一個叫 bcrypt 的第三方庫,它是被專門設計出來哈希密碼的。
PyCrypto 可能是 Python 中密碼學方面最有名的第三方軟件包。可惜的是,它的開發工作于 2012 年就已停止。其他人還在繼續發布最新版本的 PyCrypto,如果你不介意使用第三方的二進制包,仍可以取得 Python 3.5 的相應版本。比如,我在 Github 上找到了對應 Python 3.5 的 PyCrypto 二進制包。
幸運的是,有一個該項目的分支 PyCrytodome 取代了 PyCrypto 。為了在 Linux 上安裝它,你可以使用以下 pip 命令:
pip install pycryptodome
在 Windows 系統上安裝則稍有不同:
pip install pycryptodomex
如果你遇到了問題,可能是因為你沒有安裝正確的依賴包(LCTT 譯注:如 python-devel),或者你的 Windows 系統需要一個編譯器。如果你需要安裝上的幫助或技術支持,可以訪問 PyCryptodome 的網站。
還值得注意的是,PyCryptodome 在 PyCrypto 最后版本的基礎上有很多改進。非常值得去訪問它們的主頁,看看有什么新的特性。
訪問了他們的主頁之后,我們可以看一些例子。在第一個例子中,我們將使用 DES 算法來加密一個字符串:
>>> from Crypto.Cipher import DES >>> key = 'abcdefgh'>>> def pad(text): while len(text) % 8 != 0: text += ' ' return text >>> des = DES.new(key, DES.MODE_ECB) >>> text = 'Python rocks!'>>> padded_text = pad(text) >>> encrypted_text = des.encrypt(text) Traceback (most recent call last): File "", line 1, in encrypted_text = des.encrypt(text) File "C:/Programs/Python/Python35-32/lib/site-packages/Crypto/Cipher/blockalgo.py", line 244, in encrypt return self._cipher.encrypt(plaintext) ValueError: Input strings must be a multiple of 8 in length >>> encrypted_text = des.encrypt(padded_text) >>> encrypted_text b'>/xfc/x1f/x16x/x87/xb2/x93/x0e/xfcH/x02/xd59VQ'
這段代碼稍有些復雜,讓我們一點點來看。首先需要注意的是,DES 加密使用的密鑰長度為 8 個字節,這也是我們將密鑰變量設置為 8 個字符的原因。而我們需要加密的字符串的長度必須是 8 的倍數,所以我們創建了一個名為 pad 的函數,來給一個字符串末尾填充空格,直到它的長度是 8 的倍數。然后,我們創建了一個 DES 的實例,以及我們需要加密的文本。我們還創建了一個經過填充處理的文本。我們嘗試著對未經填充處理的文本進行加密,啊歐,報了一個 ValueError 錯誤!我們需要對經過填充處理的文本進行加密,然后得到加密的字符串。代碼為:encrypted_text = des.encrypt(padded_text.encode('utf-8'))
知道了如何加密,還要知道如何解密:
>>> des.decrypt(encrypted_text) b'Python rocks! '
幸運的是,解密非常容易,我們只需要調用 des 對象的 decrypt 方法就可以得到我們原來的 byte 類型字符串了。下一個任務是學習如何用 RSA 算法加密和解密一個文件。首先,我們需要創建一些 RSA 密鑰。
如果你希望使用 RSA 算法加密數據,那么你需要擁有訪問 RAS 公鑰和私鑰的權限,否則你需要生成一組自己的密鑰對。在這個例子中,我們將生成自己的密鑰對。創建 RSA 密鑰非常容易,所以我們將在 Python 解釋器中完成。
>>> from Crypto.PublicKey import RSA >>> code = 'nooneknows'>>> key = RSA.generate(2048) >>> encrypted_key = key.exportKey(passphrase=code, pkcs=8, protection="scryptAndAES128-CBC") >>> with open('/path_to_private_key/my_private_rsa_key.bin', 'wb') as f: f.write(encrypted_key) >>> with open('/path_to_public_key/my_rsa_public.pem', 'wb') as f: f.write(key.publickey().exportKey())
首先我們從 Crypto.PublicKey 包中導入 RSA,然后創建一個傻傻的密碼。接著我們生成 2048 位的 RSA 密鑰。現在我們到了關鍵的部分。為了生成私鑰,我們需要調用 RSA 密鑰實例的 exportKey 方法,然后傳入密碼,使用的 PKCS 標準,以及加密方案這三個參數。之后,我們把私鑰寫入磁盤的文件中。
接下來,我們通過 RSA 密鑰實例的 publickey 方法創建我們的公鑰。我們使用方法鏈調用 publickey 和 exportKey 方法生成公鑰,同樣將它寫入磁盤上的文件。
加密文件
有了私鑰和公鑰之后,我們就可以加密一些數據,并寫入文件了。這里有個比較標準的例子:
from Crypto.PublicKey import RSA from Crypto.Random import get_random_bytes from Crypto.Cipher import AES, PKCS1_OAEP with open('/path/to/encrypted_data.bin', 'wb') as out_file: recipient_key = RSA.import_key( open('/path_to_public_key/my_rsa_public.pem').read()) session_key = get_random_bytes(16) cipher_rsa = PKCS1_OAEP.new(recipient_key) out_file.write(cipher_rsa.encrypt(session_key)) cipher_aes = AES.new(session_key, AES.MODE_EAX) data = b'blah blah blah Python blah blah' ciphertext, tag = cipher_aes.encrypt_and_digest(data) out_file.write(cipher_aes.nonce) out_file.write(tag) out_file.write(ciphertext)
代碼的前三行導入 PyCryptodome 包。然后我們打開一個文件用于寫入數據。接著我們導入公鑰賦給一個變量,創建一個 16 字節的會話密鑰。在這個例子中,我們將使用混合加密方法,即 PKCS#1 OAEP ,也就是最優非對稱加密填充。這允許我們向文件中寫入任意長度的數據。接著我們創建 AES 加密,要加密的數據,然后加密數據。我們將得到加密的文本和消息認證碼。最后,我們將隨機數,消息認證碼和加密的文本寫入文件。
順便提一下,隨機數通常是真隨機或偽隨機數,只是用來進行密碼通信的。對于 AES 加密,其密鑰長度最少是 16 個字節。隨意用一個你喜歡的編輯器試著打開這個被加密的文件,你應該只能看到亂碼。
現在讓我們學習如何解密我們的數據。
from Crypto.PublicKey import RSA from Crypto.Cipher import AES, PKCS1_OAEP code = 'nooneknows'with open('/path/to/encrypted_data.bin', 'rb') as fobj: private_key = RSA.import_key( open('/path_to_private_key/my_rsa_key.pem').read(), passphrase=code) enc_session_key, nonce, tag, ciphertext = [ fobj.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1) ] cipher_rsa = PKCS1_OAEP.new(private_key) session_key = cipher_rsa.decrypt(enc_session_key) cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce) data = cipher_aes.decrypt_and_verify(ciphertext, tag)print(data)
如果你認真看了上一個例子,這段代碼應該很容易解析。在這里,我們先以二進制模式讀取我們的加密文件,然后導入私鑰。注意,當你導入私鑰時,需要提供一個密碼,否則會出現錯誤。然后,我們文件中讀取數據,首先是加密的會話密鑰,然后是 16 字節的隨機數和 16 字節的消息認證碼,最后是剩下的加密的數據。
接下來我們需要解密出會話密鑰,重新創建 AES 密鑰,然后解密出數據。
你還可以用 PyCryptodome 庫做更多的事。不過我們要接著討論在 Python 中還可以用什么來滿足我們加密解密的需求。
Cryptography 的目標是成為“人類易于使用的密碼學包,就像 requests 是“人類易于使用的 HTTP 庫”一樣。這個想法使你能夠創建簡單安全、易于使用的加密方案。如果有需要的話,你也可以使用一些底層的密碼學基元,但這也需要你知道更多的細節,否則創建的東西將是不安全的。
如果你使用的 Python 版本是 3.5, 你可以使用 pip 安裝,如下:
pip install cryptography
你會看到 cryptography 包還安裝了一些依賴包,如果安裝都順利,我們就可以試著加密一些文本了。讓我們使用 Fernet 對稱加密算法,它保證了你加密的任何信息在不知道密碼的情況下不能被篡改或讀取。Fernet 還通過 MultiFernet 支持密鑰輪換。下面讓我們看一個簡單的例子:
>>> from cryptography.fernet import Fernet >>> cipher_key = Fernet.generate_key() >>> cipher_key b'APM1JDVgT8WDGOWBgQv6EIhvxl4vDYvUnVdg-Vjdt0o='>>> cipher = Fernet(cipher_key) >>> text = b'My super secret message'>>> encrypted_text = cipher.encrypt(text) >>> encrypted_text (b'gAAAAABXOnV86aeUGADA6mTe9xEL92y_m0_TlC9vcqaF6NzHqRKkjEqh5d21PInEP3C9HuiUkS9f'b'6bdHsSlRiCNWbSkPuRd_62zfEv3eaZjJvLAm3omnya8=') >>> decrypted_text = cipher.decrypt(encrypted_text) >>> decrypted_text b'My super secret message'
首先我們需要導入 Fernet,然后生成一個密鑰。我們輸出密鑰看看它是什么樣兒。如你所見,它是一個隨機的字節串。如果你愿意的話,可以試著多運行 generate_key 方法幾次,生成的密鑰會是不同的。然后我們使用這個密鑰生成 Fernet 密碼實例。
現在我們有了用來加密和解密消息的密碼。下一步是創建一個需要加密的消息,然后使用 encrypt 方法對它加密。我打印出加密的文本,然后你可以看到你再也讀不懂它了。為了解密出我們的秘密消息,我們只需調用 decrypt 方法,并傳入加密的文本作為參數。結果就是我們得到了消息字節串形式的純文本。
關于“Python3常見加密計數方法有哪些”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Python3常見加密計數方法有哪些”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。