使用 pyca/cryptography 的 DES 密码 (PBEWithMD5AndDES)

问题描述 投票:0回答:2

为了支持某些遗留应用程序,我需要在 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)


**更新**:

感谢@SquareRootOfTwentyThree,我最终得到了这个:
(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]
python cryptography pycrypto
2个回答
4
投票

有没有办法使用 pyca/密码学(单一)DES 加密某些东西?

是的,只需将 8 字节密钥传递给

cryptography.hazmat.primitives.ciphers.algorithms.TripleDES
即可。这将为三重 DES 中的每个 DES 转换使用相同的密钥。

Triple-DES 也称为 DES-EDE,即加密、解密然后加密。如果您对每个密钥使用相同的密钥,则加密/解密对之一将产生身份函数,仅留下单个 DES 加密。


请注意,并非所有三重 DES 实现都接受单个密钥(因为通常存在单个 DES),但这个可以:

秘钥。这必须保密。

64
128
192
位长。 DES 仅使用密钥的
56
112
168
位,因为密钥的每个组成部分都有一个奇偶校验字节。有些文字提到最多有三个单独的密钥,每个密钥都有
56
位长,可以简单地将它们连接起来以生成完整的密钥。

尽管我必须承认,您必须了解三重 DES 的工作原理才能理解该文本。

另请注意,单个 DES 的 DES-EDE 实现目前尚未优化,它执行所有三个操作,即使其中两个操作相互抵消。


0
投票

感谢@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'
© www.soinside.com 2019 - 2024. All rights reserved.