Decrypting strings in Python that were encrypted with MCRYPT_RIJNDAEL_256 in PHP

后端 未结 3 658
失恋的感觉
失恋的感觉 2020-11-30 08:48

I have a function in PHP that encrypts text as follows:

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

    return trim(base64_encode(mcrypt_encrypt(MCRYPT_         


        
3条回答
  •  再見小時候
    2020-11-30 09:29

    To decrypt this form of encryption, you will need to get a version of Rijndael. One can be found here. Then you will need to simulate the key and text padding used in the PHP Mcrypt module. They add '\0' to pad out the text and key to the correct size. They are using a 256 bit block size and the key size used with the key you give is 128 (it may increase if you give it a bigger key). Unfortunately, the Python implementation I've linked to only encodes a single block at a time. I've created python functions which simulate the encryption (for testing) and decryption in 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
    

    This can be used as follows:

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

    For comparison, here is the output from PHP with the same text:

    $ 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=
    

提交回复
热议问题