Love and miss ya, Douglas. I bet you were shocked. |
This isn’t a tutorial.
If you’ve found this post then I’m guessing you’ve already been trying to use mcrypt in php, and you’re on your fourth cup of coffee, ready to trade up for something stronger.
The Hitch-Hiker’s Guide to the Galaxy also mentions alcohol. It says that the best drink in existence is the Pan Galactic Gargle Blaster, the effect of which is like having your brains smashed out with a slice of lemon wrapped round a large gold brick.
ntpxSD3GoDMISWoNBiYq6w=COcq_Q0daVEx9z6qyHmZefrfBbhSIp-lg9_E76eloLw4S1yjf5SAh-eXd2zXe3N6YQQPI4QDSD4St2J8GVkvAyyj3BdkRI2CUg8OeFXr7CwmEe-up7g9ju8F7uFAUQiOluyptjXikVyplTh0QAV4g08MrNnr0dVwhU6e5hGSxxkJD90FEICgFpHtkKmMwkShaC7v7dAM4QyZUI2NGxLdIRjxe_FHLWrHeX-GsIB7rdCTvJFNkRVeYasvtl8SWVlLqJfP93JcDJGhptWO1mZ0bovQE-m3PQv6E9u0dCLVN_nRgIclX4BnC-EiV45mf397PDFXPksKA_CdNGhFnfFzZw=9f19e23e02ad7abd246e866c1d8d2f0a
The Hitch-Hiker’s Guide to the Galaxy also mentions alcohol. It says that the best drink in existence is the Pan Galactic Gargle Blaster, the effect of which is like having your brains smashed out with a slice of lemon wrapped round a large gold brick.
The string returned by CRYPT::encrypt() is encoded properly for a URL (if you really want to go that way) and includes the initialization vector and a hash of the original plaintext.
Of course, the original IV is required to decrypt in ECB mode. It’s safe to send it anywhere, but if you want to be really sneaky you could store the IV in a database and send an identifier for the database row. Or you could use the hash as a key in the database to find the IV. OR OR OR you could write the IVs on sticky notes. There’s plenty of help out there on these web things about encryption and initialization vectors.
The MD5 hash of the key plus the original plaintext is sent along as a fingerprint so the decrypt function can be sure what was decrypted is valid. Someone can send just a bunch of crap back, or a character could be lost. Who knows? No matter what happens, if the text sent to decrypt isn’t exactly what came out of encrypt then the hash will not match (except for one chance in a zillion… look up MD5 sometime).
I hope this helps you! You can click on function names to bring up the php.net documentation.
// base64url encode/decode from
// http://www.php.net/manual/en/function.base64-encode.php#103849
//
// These are good to have in case you want to put some binary data into
// a uri. Thay also remove and return the base64 padding characters (=)
function base64url_encode($data)
{
return rtrim(strtr(base64_encode($data), ‘+/’, ‘-_’), ‘=’);
}
function
base64url_decode($data){
return base64_decode(str_pad(strtr($data, ‘-_’, ‘+/’), strlen($data) % 4, ‘=’, STR_PAD_RIGHT));
}
// I wrote this class. Of course, the mcrypt stuff is from examples
// on php.net.
class CRYPT
{
// TWOFISH accepts a 256-bit key — that’s 32 characters
protected static $key = ‘ThisisaREALLYSECRETKEY..hi.ho…’;
public static function
encrypt($plaintext){
$td = mcrypt_module_open(MCRYPT_TWOFISH, “”, MCRYPT_MODE_ECB, “”);
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, CRYPT::$key, $iv);
$ciphertext = mcrypt_generic($td, $plaintext);
mcrypt_generic_deinit($td);
// Encode the iv and cipher text, compute an md5 hash
// Return a string concatenating them between =’s
return base64url_encode($iv) . ‘=’ . base64url_encode($ciphertext) . ‘=’ . md5(CRYPT::$key . $plaintext);
}
// Split the string up, decrypt, and then compute the hash on the plaintext
// the hash has to match what was in the string or the cipher text was not
// right.
public static function decrypt($encodedCiphertext)
{
$parts = preg_split(‘/=/’, $encodedCiphertext);
if (count($parts) != 3) {
debug_str(“INVALID encodedCipher in CRYPT::decrypt”);
return null;
}
$iv = base64url_decode($parts[0]);
$ciphertext = base64url_decode($parts[1]);
$hash = $parts[2];
$td = mcrypt_module_open(MCRYPT_TWOFISH, “”, MCRYPT_MODE_ECB, “”);
mcrypt_generic_init($td, CRYPT::$key, $iv);
$plaintext = trim(mdecrypt_generic($td, $ciphertext), “