为了支持某些遗留应用程序,我需要在 python 中实现
PBEWithMD5AndDES
(RFC2898 第 6.1 节)。我知道这是不安全的,已被弃用,不应再使用。但这可悲的是我的要求。
我已经有一个使用
PyCrypto
/PyCryptodome
的工作版本,但我需要引入 PyCryptodome
作为项目的附加依赖项,这是我想避免的。由于我们已经在代码的其他部分使用了 pyca/cryptography
,因此我更喜欢这个库而不是 PyCrypto(dome)
。然而,由于 PBEWithMD5AndDES
的性质,我需要 DES 加密支持,但据我所知,pyca/cryptography
仅支持三重 DES (3DES)。
有没有办法使用
pyca/cryptography
进行(单一)DES 加密?基本上我需要用 Crypto.Cipher.DES
中的内容替换 pyca/cryptography
的以下用法:
key, init_vector = _pbkdf1_md5(a_password, a_salt, a_iterations)
cipher = DES.new(key, DES.MODE_CBC, init_vector)
encrypted_message = cipher.encrypt(encoded_message)
(key, init_vector) = _pbkdf1_md5(a_password, a_salt, a_iterations)
cipher = Cipher(algorithms.TripleDES(key), modes.CBC(init_vector), default_backend())
encryptor = self.cipher.encryptor()
encrypted = encryptor.update(encoded_message)
encryptor.finalize()
def _pbkdf1_md5(a_password, a_salt, a_iterations):
digest = Hash(MD5(), default_backend())
digest.update(a_password)
digest.update(a_salt)
key = None
for i in range(a_iterations):
key = digest.finalize()
digest = Hash(MD5(), default_backend())
digest.update(key)
digest.finalize()
return key[:8], key[8:16]
有没有办法使用 pyca/密码学(单一)DES 加密某些东西?
是的,只需将 8 字节密钥传递给
cryptography.hazmat.primitives.ciphers.algorithms.TripleDES
即可。这将为三重 DES 中的每个 DES 转换使用相同的密钥。
Triple-DES 也称为 DES-EDE,即加密、解密然后加密。如果您对每个密钥使用相同的密钥,则加密/解密对之一将产生身份函数,仅留下单个 DES 加密。
请注意,并非所有三重 DES 实现都接受单个密钥(因为通常存在单个 DES),但这个可以:
秘钥。这必须保密。
、64
或128
位长。 DES 仅使用密钥的192
、56
或112
位,因为密钥的每个组成部分都有一个奇偶校验字节。有些文字提到最多有三个单独的密钥,每个密钥都有168
位长,可以简单地将它们连接起来以生成完整的密钥。56
尽管我必须承认,您必须了解三重 DES 的工作原理才能理解该文本。
另请注意,单个 DES 的 DES-EDE 实现目前尚未优化,它将执行所有三个操作,即使其中两个操作相互抵消。
感谢@SquareRootOfTwentyThre,我的DES-ECB示例:
PyCrypto/PyCryptodome
pip 安装 pycryptodome
import base64
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad,unpad
key = "the key"
key = key.encode("utf-8")
key = (key + b'\0' * (8 - len(key) % 8))[:8]
des = DES.new(key, DES.MODE_ECB)
data = "Hello World"
# Encrypt
data_p = pad(data.encode("utf-8"), 8, 'pkcs7')
result = des.encrypt(data_p)
b64result = base64.b64encode(result)
print("Input Key:", key)
print("Pad Data: ", data_p)
print("Encrypt Result: ",result)
print("base64 Result: ", b64result)
# Decrypt
# decrypt_data = des.decrypt(result)
# Or from the base64 format
decrypt_data = des.decrypt(base64.b64decode(b64result))
origin_data = unpad(decrypt_data, 8, 'pkcs7')
print('Decrypt:',origin_data)
结果:
Input Key: b'the key\x00'
Pad Data: b'Hello World\x05\x05\x05\x05\x05'
Encrypt Result: b'\x9c\x93\x85\xe4\xc7?\x87\x157 FuLq\xbe\xd8'
base64 Result: b'nJOF5Mc/hxU3IEZ1THG+2A=='
Decrypt: b'Hello World'
pyca/密码学
pip 安装密码学
import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
key = "the key"
key = key.encode("utf-8")
key = (key + b'\0' * (8 - len(key) % 8))[:8]
cipher = Cipher(algorithms.TripleDES(key), modes.ECB())
data = "Hello World"
# Encrypte
padder = padding.PKCS7(64).padder()
data_p = padder.update(data.encode("utf-8")) + padder.finalize()
encryptor = cipher.encryptor()
result = encryptor.update(data_p) + encryptor.finalize()
b64result = base64.b64encode(result)
print("Input Key:", key)
print("Pad Data: ", data_p)
print("Encrypt Result: ",result)
print("base64 Result: ", b64result)
# Decrypte
decryptor = cipher.decryptor()
# decrypt_data = decryptor.update(result)
# Or from base64 format
decrypt_data = decryptor.update(base64.b64decode(b64result))
unpadder = padding.PKCS7(64).unpadder()
origin_data = unpadder.update(decrypt_data) + unpadder.finalize()
print('Decrypt:',origin_data)
结果:
Input Key: b'the key\x00'
Pad Data: b'Hello World\x05\x05\x05\x05\x05'
Encrypt Result: b'\x9c\x93\x85\xe4\xc7?\x87\x157 FuLq\xbe\xd8'
base64 Result: b'nJOF5Mc/hxU3IEZ1THG+2A=='
Decrypt: b'Hello World'