Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中解密使用MCRYPT_RIJNDAEL_256加密的Python字符串_Php_Python_Encryption_Mcrypt - Fatal编程技术网

在PHP中解密使用MCRYPT_RIJNDAEL_256加密的Python字符串

在PHP中解密使用MCRYPT_RIJNDAEL_256加密的Python字符串,php,python,encryption,mcrypt,Php,Python,Encryption,Mcrypt,我在PHP中有一个加密文本的函数,如下所示: function encrypt($text) { $Key = "MyKey"; return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $Key, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RA

我在PHP中有一个加密文本的函数,如下所示:

function encrypt($text)
{
    $Key = "MyKey";

    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $Key, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
key = 'MyKey'
text = 'test'

encoded = encrypt(key, text)
print repr(encoded)
# prints 'I+KlvwIK2e690lPLDQMMUf5kfZmdZRIexYJp1SLWRJY='

decoded = decrypt(key, encoded)
print repr(decoded)
# prints 'test'

如何在Python中解密这些值

要解密这种形式的加密,您需要获得Rijndael的版本。可以找到一个。然后需要模拟PHP Mcrypt模块中使用的键和文本填充。它们添加
“\0”
,以将文本和键填充到正确的大小。它们使用的是256位块大小,与您提供的密钥一起使用的密钥大小为128(如果您提供更大的密钥,则可能会增加)。不幸的是,我链接到的Python实现一次只编码一个块。我创建了python函数,这些函数模拟python中的加密(用于测试)和解密

import rijndael
import base64

KEY_SIZE = 16
BLOCK_SIZE = 32

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

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

    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


def decrypt(key, encoded):
    padded_key = key.ljust(KEY_SIZE, '\0')

    ciphertext = base64.b64decode(encoded)

    r = rijndael.rijndael(padded_key, BLOCK_SIZE)

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

    plaintext = padded_text.split('\x00', 1)[0]

    return plaintext
这可以按如下方式使用:

function encrypt($text)
{
    $Key = "MyKey";

    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $Key, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
key = 'MyKey'
text = 'test'

encoded = encrypt(key, text)
print repr(encoded)
# prints 'I+KlvwIK2e690lPLDQMMUf5kfZmdZRIexYJp1SLWRJY='

decoded = decrypt(key, encoded)
print repr(decoded)
# prints 'test'
为了进行比较,以下是PHP的输出,其中包含相同的文本:

$ php -a
Interactive shell

php > $key = 'MyKey';
php > $text = 'test';
php > $output = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB);
php > $encoded = base64_encode($output);
php > echo $encoded;
I+KlvwIK2e690lPLDQMMUf5kfZmdZRIexYJp1SLWRJY=

如果您愿意在PHP端使用MCRYPT_RIJNDAEL_128而不是256,那么这很简单:

from Crypto.Cipher import AES
import base64
key="MyKey"

def decrypt(text)
    cipher=AES.new(key)
    return cipher.decrypt(base64.b64decode(text))

尽管当时@101100的答案是好的,但它不再可行。该引用现在是一个断开的链接,代码只能在较旧的python上运行(没有人可以解密这个,你扔掉iv。@hop-ECB模式可以在没有iv的情况下解密。iv在ECB模式下不用于加密或解密。@Birrree:对!我只看到iv参数被设置和假设了……这说明了为什么你不在一行中编写整个程序。@dharmesh-我正试图解决你的问题,但没有感谢PHP,
MCRYPT_RIJNDAEL_256
算法与
AES 256
算法不同(RIJNDAEL中进行了更多轮)。我必须找到一个Python实现或纯Rijndael 256,它看起来不像PyCrypto或M2Crypto支持。@dharmesh:为什么不首先在php端使用一些常见的东西呢?太棒了!我能够让您的测试代码运行。然后,我运行了解密函数(在Python中)针对PHP中的加密值。工作起来很有魅力。非常感谢。除了键len>块大小部分之外,您还应该使用string.ljust()来填充键。@hop感谢string.ljust()的提示。我已经更新了键填充以使用它。文本填充看起来还是用另一种方式更好。@101100使用“pip install rijndael”但给出了错误。r=rijndael.rijndael(填充键,块大小)AttributeError:'module'对象没有属性'rijndael'@101100我尝试过这段代码,但它的给我属性错误“AttributeError:'module'对象没有属性'rijndael'“谢谢。我认为值得注意的是,
加密
模块可以在中找到。