In the (not too distant) past a decision has been made (by someone who longer works here) to always 'encrypt' database IDs to something else, on the fly, whenever it was needed for external communication.
Now, we've moved from PHP 5.x to PHP 7.0 for our main application, and our microservices scattered across our infrastructure are running either 7.0 or 7.1. The 7.1 servers keep throwing deprecation warnings for the mcrypt stuff. No biggie, just yet. But with PHP 7.2 around the corner, we want to keep updating and upgrading. Mcrypt is blocking.
To save all the currently encrypted values in 60 tables, across 1400 databases, is a huge task. Is there a way to leverage OpenSSL, with Blowfish and ECB, to get the same encoded and decoded values to lull us into a false sense of security? All so we can plan our database migrations far ahead.
Basically, the currently encrypted value is this:
item:13fb7533bf19399ff114468b194ebfaf
This is ID 123
. It goes through the following functions to get to this string:
$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, for the other way around:
$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've tried it for several hours, but I'm completely blindsided by anything 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 similiar to ��IY_Lc�d:�_���
. Could anyone shine any light on this -- is it even possible?
\0
inopenssl_blowfish_decrypt_hex
to not remove spaces and 0s. I think last line should look likereturn trim($decrypted, "\0");
– Tersina