Migrating from mcrypt with Blowfish and ECB to OpenSSL

In (not too far) the past decision was made (by someone who already works here) to always "encrypt" the database identifiers on something else, on the fly, when it was necessary for external communication.

Now we have moved from PHP 5.x to PHP 7.0 for our main application, and our microservices scattered throughout our infrastructure work with either 7.0 or 7.1. 7.1 servers keep obsolete warnings for mcrypt files. There hasn’t been anything yet. But with PHP 7.2 around the corner, we want to keep updating and updating. Mcrypt is blocking.

Keeping all encrypted values ​​in 60 tables, in 1,400 databases, is a huge task. Is there a way to use OpenSSL, with Blowfish and ECB, to get the same encoded and decoded values ​​to lull us with a false sense of security? Everything so that we can plan the database migration far ahead.

Basically, the currently encrypted value is:

item:13fb7533bf19399ff114468b194ebfaf

This is an identifier 123. The following functions are used to access this line:

$id   = 123;
$type = 'item';

$serialized = serialize('' . $id); // To make sure always a string gets put in

$ivSize = mcrypt_create_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB), MCRYPT_RAND);
$iv     = mcrypt_create_iv($ivSize);

$passCrypt = mcrypt_encrypt(MCRYPT_BLOWFISH, $type, $serialized, MCRYPT_MODE_ECB, $iv);
$encoded   = bin2hex($passCrypt); // `13fb7533bf19399ff114468b194ebfaf`

$encryptedId = $type . ':' . $encoded;

This gives the final result item:13fb7533bf19399ff114468b194ebfaf.

Now, vice versa:

$encryptedId = 'item:13fb7533bf19399ff114468b194ebfaf';

$type = 'item';
$encryptedIdOnly = substr($encryptedId, strlen($type) + 1); // `13fb...`

$decoded   = hex2bin($encryptedIdOnly);
$iv        = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB), MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_BLOWFISH, 'item', $decoded, MCRYPT_MODE_ECB, $iv); // This gives ' `s:3:"123";` '

$unserialized = unserialize($decrypted); // '123'

I tried it for several hours, but I am completely stunned by something crypto (but I want to learn!). My current code is:

$cipher = 'BF-ECB';
//$cipher = 'BF'; (I've tried both, no difference)

$isCtypeXDigit = ctype_xdigit($decipher);
$decoded       = hex2bin($decipher);
$ivLength      = openssl_cipher_iv_length($cipher);
$randomBytes   = openssl_random_pseudo_bytes($ivLength);
$decrypted     = openssl_decrypt($decoded, $cipher, $prefix, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $randomBytes);
$unserialized  = unserialize($decrypted);

Which gives me a thousand things, all similar to IY_Lc d: _ . Can anyone shed light on this - is this possible?

+4
1

. .

# cat a.php
<?php
function mcrypt_blowfish_encrypt_hex($key, $str)
{
    $encrypted = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $str, MCRYPT_MODE_ECB);
    return bin2hex($encrypted);
}

function make_openssl_blowfish_key($key)
{
    if("$key" === '')
        return $key;

    $len = (16+2) * 4;
    while(strlen($key) < $len) {
        $key .= $key;
    }
    $key = substr($key, 0, $len);
    return $key;
}

function openssl_blowfish_encrypt_hex($key, $str)
{
    $blockSize = 8;
    $len = strlen($str);
    $paddingLen = intval(($len + $blockSize - 1) / $blockSize) * $blockSize - $len;
    $padding = str_repeat("\0", $paddingLen);
    $data = $str . $padding;
    $key = make_openssl_blowfish_key($key);
    $encrypted = openssl_encrypt($data, 'BF-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
    return bin2hex($encrypted);
}

function openssl_blowfish_decrypt_hex($key, $hex)
{
    $key = make_openssl_blowfish_key($key);
    $decrypted = openssl_decrypt(hex2bin($hex), 'BF-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
    return trim($decrypted);
}


function test()
{
    for($i = 1; $i < 32; $i++) {
        for($j = 1; $j < 32; $j++) {
            $key = str_repeat('' . rand(0, 9), $j);
            $str = str_repeat('' . rand(0, 9), $i);

            $encoded_openssl = openssl_blowfish_encrypt_hex($key, $str);
            $decoded_openssl = openssl_blowfish_decrypt_hex($key, $encoded_openssl);
            if($decoded_openssl != $str)
                die("encrypt($key, $str) wrong: $encoded_openssl: decrypt failed\n");


            if(function_exists('mcrypt_encrypt')) {
                $encoded_mcrypt = mcrypt_blowfish_encrypt_hex($key, $str);
                if($encoded_openssl != $encoded_mcrypt)
                    die("encrypt($key, $str) wrong: $encoded_openssl, mcrypt=$encoded_mcrypt\n");
            }

            echo "key='$key', str='$str', encrypted='$encoded_openssl'\n";
        }
    }
}

echo "openssl: thisismyitemyes:" . openssl_blowfish_encrypt_hex('thisismyitemyes', serialize('6918')) . "\n";
echo "openssl: headphone:" . openssl_blowfish_encrypt_hex('headphone', serialize('581856')) . "\n";

test();

, :

# php a.php
openssl: thisismyitemyes:b192ac0f6105416a710aec3ce92b1085
openssl: headphone:ef057c036eb024865406838c62590a93
key='7', str='3', encrypted='945b638624ecbd5e'
key='22', str='1', encrypted='3daf096bdc744d8a'
key='888', str='0', encrypted='b164bb0b603f439e'
key='2222', str='9', encrypted='d3458df30aef0b4b'
...
...
key='3333333333333333333333333333333', str='11111111111111111111111111111', encrypted='b0c9bf45d6f5c7b3b0c9bf45d6f5c7b3b0c9bf45d6f5c7b363a25777c712f1d5'
key='4444444444444444444444444444444', str='999999999999999999999999999999', encrypted='dd6aaf466121c0f6dd6aaf466121c0f6dd6aaf466121c0f659a2271369ab6731'
key='7777777777777777777777777777777', str='3333333333333333333333333333333', encrypted='6591e9cc92a6473a6591e9cc92a6473a6591e9cc92a6473a208a7a562babc60c'

:

+3

Source: https://habr.com/ru/post/1694642/


All Articles