OpenSSL AES'den python'da AES CBC'nin şifresini çözme

Sep 30 2020

Python ile OpenSSL'de şifrelenmiş bir dosyanın şifresini çözmem gerekiyor, ancak pycrypto seçeneklerini anlamıyorum.

İşte OpenSSL'de yaptığım şey

  1. openssl enc -aes-256-cbc -a -salt -pbkdf2 -iter 100000 -in "clear.txt" -out "crypt.txt" -pass pass: "mypassword"

  2. openssl enc -d -aes-256-cbc -a -pbkdf2 -iter 100000 -in "crypt.txt" -out "out.txt" -pass pass: "mypassword"

Denedim (belli ki işe yaramayacak)

obj2 = AES.new("mypassword", AES.MODE_CBC)
output = obj2.decrypt(text)

Sadece python'da ikinci adımı yapmak istiyorum, ancak örneğe baktığımda:

https://pypi.org/project/pycrypto/

obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
obj2.decrypt(ciphertext)

IV'ye ihtiyacım yok, tuzu nasıl belirtebilirim? pbkdf2 karması? Ben de bu konuya baktım

Python'da OpenSSL AES ile şifrelenmiş dosyaların şifresini nasıl çözebilirim?

ama yardımcı olmadı.

Birisi bana bunu python kullanarak nasıl yapacağımı gösterebilir mi?

teşekkür ederim.

Yanıtlar

4 Topaco Sep 30 2020 at 04:16

OpenSSL deyimi, 32 baytlık bir anahtar ve 16 baytlık bir IV oluşturmak için PBKDF2'yi kullanır. Bunun için, örtük olarak rastgele 8 baytlık bir tuz oluşturulur ve belirtilen parola, yineleme sayısı ve özet (varsayılan: SHA-256) uygulanır. Anahtar / IV çifti, düz metni CBC modunda AES-256 ve PKCS7 dolgusu ile şifrelemek için kullanılır. burada . Sonuç, Salted__' in 8 baytlık ASCII kodlamasıyla başlayan OpenSSL biçiminde döndürülür , ardından 8 baytlık tuz ve tümü Base64 kodlanmış gerçek şifreli metin gelir. Şifre çözme için tuz gereklidir, böylece anahtar ve IV yeniden yapılandırılabilir.

OpenSSL ifadesindeki parolanın gerçekte tırnak işaretleri olmadan aktarıldığına dikkat edin, yani yayınlanan OpenSSL ifadesinde tırnak işaretleri parolanın bir parçasıdır.

Python'da şifre çözme için öncelikle tuz ve gerçek şifreli metin şifrelenmiş verilerden belirlenmelidir. Tuz ile anahtar / IV çifti yeniden yapılandırılabilir. Son olarak, anahtar / IV çifti şifre çözme için kullanılabilir.

Örnek: Yayınlanan OpenSSL deyimiyle, düz metin

The quick brown fox jumps over the lazy dog

şifreli metne şifrelenmiş

U2FsdGVkX18A+AhjLZpfOq2HilY+8MyrXcz3lHMdUII2cud0DnnIcAtomToclwWOtUUnoyTY2qCQQXQfwDYotw== 

Python ile şifre çözme şu şekilde mümkündür ( PyCryptodome kullanarak ):

from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256
from Crypto.Util.Padding import unpad
from Crypto.Cipher import AES
import base64

# Determine salt and ciphertext
encryptedDataB64 = 'U2FsdGVkX18A+AhjLZpfOq2HilY+8MyrXcz3lHMdUII2cud0DnnIcAtomToclwWOtUUnoyTY2qCQQXQfwDYotw=='
encryptedData = base64.b64decode(encryptedDataB64)
salt = encryptedData[8:16]
ciphertext = encryptedData[16:]

# Reconstruct Key/IV-pair
pbkdf2Hash = PBKDF2(b'"mypassword"', salt, 32 + 16, count=100000, hmac_hash_module=SHA256)
key = pbkdf2Hash[0:32]
iv = pbkdf2Hash[32:32 + 16]

# Decrypt with AES-256 / CBC / PKCS7 Padding
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(cipher.decrypt(ciphertext), 16)

print(decrypted)

Düzenleme - Yorumunuzla ilgili olarak: 16 MB mümkün olmalıdır, ancak daha büyük veriler için şifreli metin genellikle bir dosyadan okunur ve şifresi çözülen veriler, yukarıda yayınlanan örneğin aksine bir dosyaya yazılır.
Verilerin tek adımda çözülüp çözülemeyeceği, sonuçta mevcut belleğe bağlıdır. Hafıza yeterli değilse, veriler parçalar halinde işlenmelidir.
Parçalar kullanıldığında, şifrelenmiş verileri Base64 kodlamak yerine doğrudan ikili biçimde depolamak daha mantıklı olacaktır. Bu, OpenSSL deyiminde -a seçeneğini atlayarak mümkündür . Aksi takdirde, her zaman blok boyutunun tam sayı katlarının (kodlanmamış şifreli metne göre) yüklendiğinden emin olunmalıdır; burada kodlanmamış şifreli metnin 3 baytı, Base64 şifreli şifreli metnin 4 baytına karşılık gelir.

İkili depolanan şifreli metin durumunda: Şifre çözme sırasında, ilk adımda yalnızca ilk blok (16 bayt) (ikili) okunmalıdır. Bundan, tuz belirlenebilir (8'den 16'ya kadar baytlar), ardından anahtar ve IV (yukarıdaki yazılan koda benzer).
Şifreli metnin geri kalanı (ikili) uygun büyüklükteki parçalar halinde okunabilir (= blok boyutunun bir katı, örneğin 1024 bayt). Her parça ayrı ayrı şifrelenir / çözülür, çoklu şifreleme / şifre çözme aramalarına bakın . Python ile parçalar halinde dosya okumak / yazmak için örneğin buraya bakın .
Daha fazla ayrıntı, ayrı bir soru kapsamında en iyi şekilde yanıtlanır.