* * A set of functions to protect low-value comment boxes, contact us * forms, etc. from spam. * * It works by recording the time the page the form is on was loaded, * and then checking to make sure that it was loaded for at least * 10 - 15 seconds, and not more than 24 hours. * * This is done by taking the current UNIX timestamp, running it through * a number of (arbitrary) reversible transformations, and then * embedding it in the form as a hidden field. When the form is * submitted, the transformations are reversed and the time the page * was loaded checked. * * Note that this is not suitable for high-value targets, as it can very * easily be bypassed and reverse-engineered by any determined human. * *********************************************** * Changelog: * 30th January 2018: * Initial Release. */ /** * Generates a new comment key. * Note that the 'encryption' used is not secure - it's just simple XOR! * It's mainly to better support verification in complex setups and * serve as a nother annoying hurdle for spammers. * TODO: Swap out the XOR for openssl AES symmetric encryption * @param string $pass The password to transform it with. Should be a pre-selected random string. * @return string A new comment key stamped at the current time. */ function key_generate($pass) { $new_key = strval(time()); // Repeat the key so that it's long enough to XOR the key with $pass_enc = str_repeat($pass, (strlen($new_key) / strlen($pass)) + 1); $new_key = $new_key ^ $pass_enc; return base64_encode(strrev($new_key)); } /** * Decodes the given key. * @param string $key The key to decode. * @param string $pass The password to decode it with. * @return int The time that the key was generated. */ function key_decode($key, $pass) { $key_dec = strrev(base64_decode($key)); // Repeat the key so that it's long enough to XOR the key with $pass_dec = str_repeat($pass, (strlen($key_dec) / strlen($pass)) + 1); return intval($key_dec ^ $pass_dec); } /** * Verifies a key. * @param string $key The key to decode and verify. * @param string $pass The password to decode the key with. * @param int $min_age The minimum required age for the key. * @param int $max_age The maximum allowed age for the key. * @return bool Whether the key is valid or not. */ function key_verify($key, $pass, $min_age, $max_age) { $age = time() - key_decode($key, $pass); return $age >= $min_age && $age <= $max_age; }