将此 php 加密函数转换为 python

Convert this php encryption function to python

我一直在尝试将此 php 函数更改为 python 但无济于事。

public static function encode($text, $KEY) {
    $pkcs5text= self::pkcs5_pad($text,16);
    $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($size, MCRYPT_RAND);
    $bin = pack('H*', bin2hex($pkcs5text) );
    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $KEY, $bin, MCRYPT_MODE_ECB, $iv);
    return base64_encode($encrypted);
}

我的Python脚本如下

import rijndael
import base64

KEY_SIZE = 16
BLOCK_SIZE = 32

def encrypt(key, plaintext):
    padded_key = key.ljust(KEY_SIZE, '[=13=]')
    padded_text = plaintext + (BLOCK_SIZE - len(plaintext) % BLOCK_SIZE) * '[=13=]'

    # could also be one of
    #if len(plaintext) % BLOCK_SIZE != 0:
    #    padded_text = plaintext.ljust((len(plaintext) / BLOCK_SIZE) + 1 * BLOCKSIZE), '[=13=]')
    # -OR-
    #padded_text = plaintext.ljust((len(plaintext) + (BLOCK_SIZE - len(plaintext) % BLOCK_SIZE)), '[=13=]')

    r = rijndael.rijndael(padded_key, BLOCK_SIZE)

    ciphertext = ''
    for start in range(0, len(padded_text), BLOCK_SIZE):
        ciphertext += r.encrypt(padded_text[start:start+BLOCK_SIZE])

    encoded = base64.b64encode(ciphertext)

    return encoded

两个脚本都从同一封邮件生成彼此不同的编码文本。我不确定我哪里出错了。如何在 rijndael 128 之上将 mcrypt 实现到 python?

鉴于您的初始化向量是在第一个示例中随机创建的,因此输出看起来与加密和 Base 64 编码不同也就不足为奇了。重要的是您可以可靠地解码和加密。

此外,您的 python 代码看起来根本没有使用初始化向量(除非库默认使用它,在本例中,它们不是)。这意味着您不会使用密码块链接,因此不如 PHP 示例安全。

传统上,未编码输出的前几个字节是初始化向量,接收方知道其长度,然后使用它来初始化解密过程。

看起来 Python 2.x 库不是特别有用,请参阅 this example here. Python 3 seems to have what you require here

此外,对于块大小,请使用 16,因为它是 AES 标准(请参阅 here),32 将不起作用。

你必须使用相同的:

  • 块大小(Rijndael 支持不同的块大小,必须使用相同的才能兼容)

    BLOCK_SIZE = 16
    
  • padding(PKCS#7 padding pad,字节数表示填充字节数)

    padbyte = BLOCK_SIZE - len(plaintext) % BLOCK_SIZE
    padded_text = plaintext + padbyte * chr(padbyte)
    

安全考虑:

切勿使用 ECB 模式。这是非常不安全的。至少使用带有随机 IV 的 CBC 模式。 IV 不必是秘密的,因此您可以将其添加到密文中并在解密之前将其切掉。

验证您的密文:使用加密然后-MAC 方案来防止(恶意)使用强 MAC 修改您的密文,例如 HMAC-SHA256 或使用像 GCM 这样的身份验证模式。