简体   繁体   中英

Decrypt data with python, encrypt in php

I get the necrypted string to pycrypto ,but it returned a incorrect result.

<?php
define('MCRYPT_SECRET_KEY', '1d46a31baeab9cf69184d1f92ba5b9f8');
function decode($encode_str) {
    $key = pack('H*',MCRYPT_SECRET_KEY);
    //var_dump($key);echo "\n";
    $iv_size = mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ECB);
    //var_dump($iv_size);echo "\n";
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    //var_dump($iv);echo "\n";

    $encode_str = str_replace(['-', '_'], ['+', '/'], $encode_str);
    $mod4 = strlen($encode_str) % 4 and $encode_str .= substr('====', $mod4);
    //var_dump($encode_str);echo "\n";
    $decrypt = base64_decode($encode_str);
    //var_dump($decrypt);echo "\n";
    $decrypt = mcrypt_decrypt(MCRYPT_3DES, $key, $decrypt, MCRYPT_MODE_ECB);

    return $decrypt;
}
echo "aFOYNZB4Ye4 : ".decode("aFOYNZB4Ye4")."\n";

result:

aFOYNZB4Ye4 : 13455

but when I use python,I could not get the correct result.

# coding: utf-8
import sys,os,base64
from Crypto.Cipher import DES3

key = "1d46a31baeab9cf69184d1f92ba5b9f8".decode("hex")

def urlsafe_mcryptdecode(idstr):
    try:
        print len(key),key,'\n'
        idstr = idstr.replace('-','+').replace('_','/')
        mod4 = len(idstr) % 4
        data=idstr+"===="[mod4:]
        #print len(data),data,'\n'
        base64_str = base64.b64decode(data)
        #print len(base64_str),base64_str,'\n'
        cipher = DES3.new(key, DES3.MODE_ECB)
        id_ = cipher.decrypt(base64_str)
        #print len(id_),id_,'\n'
        return id_
    except Exception,e:
        print "ERROR",e
        return idstr+"#error"

print urlsafe_mcryptdecode("aFOYNZB4Ye4")

result is not 13455.

Before the decrypt,every result of all output is same. What's wrong with my code? Thanks.

The problem is that prior to PHP 5.6.0 the function mcrypt_decrypt() silently pads the key. Your key is 16 bytes, however, the key needs to be 24 bytes, and so it is padded internally to 24 bytes with trailing NUL bytes. This is mentioned in the newer PHP documentation for mcrypt_decrypt() - see the Changelog section.

You need to take this into account when decrypting in Python. You can do that by appending NUL bytes to the end of the decoded key using ljust() :

key = "1d46a31baeab9cf69184d1f92ba5b9f8".decode("hex").ljust(24, '\0')

or

key = "1d46a31baeab9cf69184d1f92ba5b9f8".decode("hex") + ('\0' * 8)

I noticed that your PHP code generates an IV which it does not use. That's fine, it's not causing a problem, just thought I'd point that out in case you think that it's being used.

Incidentally, if you are using PHP >= 5.6.0, you need to explicitly pad the key, or use a 24 byte key in the first place. In your code you can pad like this:

$key = pack('H*x8', MCRYPT_SECRET_KEY);

which will append an additional 8 NUL bytes to the end of the key.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM