Cryptanalysis
在這個簡短的程式碼範例中如何使用密碼學是否存在問題?
我想加密一些小文本文件,這樣我就可以將它們放到網上,不受限制的訪問(不是最好的主意,但它既便宜又簡單)。我知道我應該使用 Truecrypt 之類的東西來代替這個,但我正在尋找更輕更簡單的東西。
import base64 import os from cryptography.fernet import Fernet from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from sys import argv if len(argv)<3: exit('please provide a password') exit() # password = b"password" password = argv[2].encode() salt = os.urandom(16) salt = b'\x03>\x8d\xd9x\x8d\xdcR\xc9\x1b-\x9c\x86\xc7\x83\x8c' kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=default_backend() ) key = base64.urlsafe_b64encode(kdf.derive(password)) # print(key) f = Fernet(key) # print(token) # print(f.decrypt(token)) # print(salt) if "encrypt" in argv: plain_src = open("plain.nogit.txt", encoding='utf8') crypted = open("crypted.nogit.txt",'w') token = f.encrypt(plain_src.read().encode()) plain_src.read().encode() # print(repr(token)) crypted.write(repr(token)) elif "decrypt" in argv: plain_src = open("plain.decrypted.nogit.txt",'w', encoding='utf8') crypted = open("crypted.nogit.txt") token = eval(crypted.read()) plain_src.write(f.decrypt(token).decode()) if open("plain.decrypted.nogit.txt", encoding='utf8').read() == open("plain.nogit.txt", encoding='utf8').read(): print('same content') else: print('different content') else: exit('provide either 1 or 2 args')
這有多安全?我知道這會將密碼留在 shell 歷史記錄中(可以刪除和清除),但我只想問這是否是加密一些簡單文本數據的正確方法。我的目標是獲得最佳比率的安全性/簡單性。你會改變什麼?有什麼建議嗎?
我看到以下安全問題:
- 基本的故意慢速密碼到密鑰轉換是 PBKDF2-HMAC。這總比沒有好,但從抵抗硬體輔助密碼破解(使用 GPU、FPGA 或 ASIC)的角度來看,這比沒有好是其中之一。現在推薦使用scrypt或Argon2 。
- PBKDF2的隨機
salt
數被固定值消除。它應該是隨機的,在加密時儲存在密文中,在解密時從密文中獲取。隨機鹽的存在是有充分理由的:防止密碼破解對手在多個使用者之間分攤工作。- 工作因數參數
iterations=100000
是固定的,不儲存在密文中。那不是面向未來的。而且好像有點低。我對 Fernet 實施的安全性沒有意見,我沒有檢查。但是,我對在文件中看到的內容有些複雜的感覺:
- 密碼到密鑰轉換的範例已經過時了(也是上述許多批評者的根本原因)。另一方面,在第二次閱讀時,我注意到它們確實連結到並內置了對 scrypt 的支持,這是一個相當令人滿意的替代方案,為此 +1。
- 該規範規定“簽名密鑰,128 位”是真正的 MAC 密鑰¹。
- 它記錄了一個 256 位 (H)MAC,考慮到密鑰大小,它是不必要的大。
- 如果可用於密碼分析的量子電腦實現,選擇 128 位密鑰進行加密和 MAC 將看起來是一個糟糕的選擇;在可預見的將來,OTOH 128 位仍然相當安全。
- 使用 AES-CBC 和 HMAC 手工製作經過身份驗證的加密已過時;現在有更好的模式,比如AES-GCM-SIV或ChaCha20-Poly1305。
其他問題:
- 該程序打開純文字,
encoding='utf8'
因此不能用於例如 jpeg 文件。- 命令行解析是呃,不合標準的。
¹我很久以前就做過/讓一個類似的術語錯誤滑倒審查,它仍然經常讓我感到難過。