note 82947 added to function.base64-encode

From: Date: Sat, 03 May 2008 03:22:05 +0000
Subject: note 82947 added to function.base64-encode
Groups: php.notes 
Request: Send a blank email to php-notes+get-139014@lists.php.net to get a copy of this message
At Andi: The last 6 chars of the decoded is used as some checksum + cryptographical salt - this prevents only in/decrementation of a primary key (ID) in an URL. But there is no obfuscation of the ID, it is visible almost immediately: the number before "-". Hackers are thus guided to this internal ID of the database record and can use this knowledge... Obfuscate better, making details a little less obvious, but not more secure: * avoid the "-" (the "checksum/salt" is always the same lenght...), * obfuscate the integer by converting ist to hex, like the hash. <?php // unchanged, thanx Tom, Andy, fsx.nr01 function base64_url_encode($input) { return strtr(base64_encode($input), '+/=', '-_,'); } function base64_url_decode($input) { return base64_decode(strtr($input, '-_,', '+/=')); } // some variables are used for clarity, they can be avoided and lines can be shortened: function encryptId($int, $TableSalt='') { global $GlobalSalt; // global secret for salt. $HashedChecksum = substr(sha1($TableSalt.$int.$GlobalSalt), 0, 6); // The length of the "HashedChecksum" is another little secret, // but when the integers are small, it reveals... $hex = dechex($int); // The integer is better obfuscated by being HEX like the hash. return base64url_encode($HashedChecksum.$hex); // reordered, alternatively use substr() with negative lengths... } function decryptId($string, $TableSalt='') { // checks if the second part of the base64 encoded string is correct. global $GlobalSalt; // global secret for salt. $parts = base64url_decode($string); $hex = substr($parts, 6); $int = hexdec($hex); $part1 = substr($parts, 0, 6); // The "checksum/salt" is always the same length return substr(sha1($TableSalt.$int.$GlobalSalt), 0, 6) === $part1 ? $int : false; // distinguish "0" and "false" } ?> There are some questions remaining: * Why should we use sha1() for such an low-security task, it needs a lot of calculation. * Would other algorithms be faster? If your goal is, to confuse ordinary users, crc32() is much faster than sha1(). (But it can reveal the "salt" which then is much more a filler than a secret.) If you want to secure against hackers, you should use strong encryption methods instead of obfuscation. Different approach: these calculations for every URL can be avoided: Take the database-ID, salt it (with a 'secret'), calculate a hash (like sha1), store it to a (unique - if you don't trust the truncated hash-algorithm any more) column in the database in addition to the primary key, index that field, and use that strange string for the URL and for the query. These calculations are done once and never again, but it costs you more memory for the database. As secure as the other solution, but much faster (at least for php). ---- Server IP: 192.35.244.50 Probable Submitter: 213.47.75.177 ---- Manual Page -- http://www.php.net/manual/en/function.base64-encode.php Edit -- https://master.php.net/note/edit/82947 Del: integrated -- https://master.php.net/note/delete/82947/integrated Del: useless -- https://master.php.net/note/delete/82947/useless Del: bad code -- https://master.php.net/note/delete/82947/bad+code Del: spam -- https://master.php.net/note/delete/82947/spam Del: non-english -- https://master.php.net/note/delete/82947/non-english Del: in docs -- https://master.php.net/note/delete/82947/in+docs Del: other reasons-- https://master.php.net/note/delete/82947 Reject -- https://master.php.net/note/reject/82947 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#139014) next »