Cryptanalysis

在這個簡短的程式碼範例中如何使用密碼學是否存在問題?

  • June 25, 2020

我想加密一些小文本文件,這樣我就可以將它們放到網上,不受限制的訪問(不是最好的主意,但它既便宜又簡單)。我知道我應該使用 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-SIVChaCha20-Poly1305

其他問題:

  • 該程序打開純文字,encoding='utf8'因此不能用於例如 jpeg 文件。
  • 命令行解析是呃,不合標準的。

¹我很久以前就做過/讓一個類似的術語錯誤滑倒審查,它仍然經常讓我感到難過。

引用自:https://crypto.stackexchange.com/questions/81540