gmm*_*mmo 6 python encryption openssl pycrypto pycryptodome
我需要使用 python 解密在 OpenSSL 上加密的文件,但我不了解 pycrypto 的选项。
这是我在 OpenSSL 中所做的
openssl enc -aes-256-cbc -a -salt -pbkdf2 -iter 100000 -in "clear.txt" -out "crypt.txt" -pass pass:"mypassword"
openssl enc -d -aes-256-cbc -a -pbkdf2 -iter 100000 -in "crypt.txt" -out "out.txt" -pass pass:"mypassword"
我试过了(这显然行不通)
obj2 = AES.new("mypassword", AES.MODE_CBC)
output = obj2.decrypt(text)
Run Code Online (Sandbox Code Playgroud)
我只想在python中做第二步,但是在查看示例时:
https://pypi.org/project/pycrypto/
obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
obj2.decrypt(ciphertext)
Run Code Online (Sandbox Code Playgroud)
我不需要IV,我如何指定盐?pbkdf2 哈希?我也在看这个线程
如何在 Python 中解密 OpenSSL AES 加密的文件?
但没有帮助。
有人可以告诉我如何使用 python 做到这一点吗?
谢谢你。
OpenSSL 语句使用 PBKDF2 创建 32 字节密钥和 16 字节 IV。为此,会隐式生成随机 8 字节盐,并应用指定的密码、迭代计数和摘要(默认值:SHA-256)。密钥/IV 对用于使用 CBC 模式下的 AES-256 和 PKCS7 填充来加密明文。这里。结果以 OpenSSL 格式返回,以Salted__的 8 字节 ASCII 编码开头,后跟 8 字节 salt 和实际密文,全部采用 Base64 编码。解密需要盐,以便可以重建密钥和IV。
注意,OpenSSL语句中的密码实际上是不带引号传递的,即在发布的OpenSSL语句中,引号是密码的一部分。
对于 Python 中的解密,必须首先从加密数据中确定盐和实际密文。使用盐可以重建密钥/IV 对。最后,密钥/IV 对可用于解密。
示例:使用发布的 OpenSSL 语句,明文
The quick brown fox jumps over the lazy dog
Run Code Online (Sandbox Code Playgroud)
被加密成密文
U2FsdGVkX18A+AhjLZpfOq2HilY+8MyrXcz3lHMdUII2cud0DnnIcAtomToclwWOtUUnoyTY2qCQQXQfwDYotw==
Run Code Online (Sandbox Code Playgroud)
使用 Python 解密如下(使用PyCryptodome):
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)
Run Code Online (Sandbox Code Playgroud)
编辑- 关于您的评论:16 MB 应该是可能的,但对于更大的数据,通常会从文件中读取密文,并将解密的数据写入文件中,与上面发布的示例相反。
数据能否一步解密最终取决于可用内存。如果内存不够,就必须分块处理数据。
当使用块时,不使用 Base64 编码加密数据而是直接以二进制格式存储它们会更有意义。这可以通过在 OpenSSL 语句中省略-a选项来实现。否则,必须确保始终加载块大小的整数倍(相对于未解码的密文),其中未解码的密文的 3 个字节对应于 Base64 编码的密文的 4 个字节。
对于二进制存储的密文:在解密过程中,第一步中仅应读取第一个块(16 字节)(二进制)。由此,可以确定盐(字节 8 到 16),然后确定密钥和 IV(类似于上面发布的代码)。
密文的其余部分可以以适当大小的块(= 块大小的倍数,例如 1024 字节)的形式(二进制)读取。每个块都是单独加密/解密的,请参阅多个加密/解密调用。有关使用 Python 读取/写入块文件的信息,请参见此处。
更多详细信息最好在单独的问题范围内得到回答。
| 归档时间: |
|
| 查看次数: |
1391 次 |
| 最近记录: |