Posted by & filed under PHP, Security.

While looking into creating an OAuth 1.0a provider using PHP, I came across this article by Rasmus Lerdorf on using the PECL OAuth extension. He had some code in place for generating a consumer key and private key pair, and it would chop up a sha1 hash and use those, which works fine and provides plenty of randomness.

I’ve personally never been a big fan of passing a bunch of hexadecimal hashes around, as it involves a lot of wasted entropy. Since hashes like this can only convey 16 different characters, they aren’t that efficient. Something like Base64 is much nicer, as it has 64 possible characters, and in theory the same data could be described in one fourth the number of characters. It’s really just a personal choice though.

Anyway, I took Rasmus’s code, and modified it a bit. Instead of generating a SHA1 (40 hex chars) and hacking that up, I generate a SHA512 (64 hex chars), and base62 encode that (which is 0-9, a-z, A-Z, leaving out the / and + and trailing = characters of base64). This way, I still get extra entropy, and don’t have the hard-to-encode characters of base64.

The code looks like this, and one pair can be generated in about 0.0006 seconds.

function gen_oauth_creds() {
	// Get a whole bunch of random characters from the OS
	$fp = fopen('/dev/urandom','rb');
	$entropy = fread($fp, 32);

	// Takes our binary entropy, and concatenates a string which represents the current time to the microsecond
	$entropy .= uniqid(mt_rand(), true);

	// Hash the binary entropy
	$hash = hash('sha512', $entropy);

	// Base62 Encode the hash, resulting in an 86 or 85 character string
	$hash = gmp_strval(gmp_init($hash, 16), 62);

	// Chop and send the first 80 characters back to the client
	return array(
		'consumer_key' => substr($hash, 0, 32),
		'shared_secret' => substr($hash, 32, 48)

Here are some example pairs of Consumer Keys and Shared Secrets generated using this code:

lInXLgx6HbF9FFq1ZQN8iSEnhzO3JVuf : 6kvwVhDGUQGXFawmulAhvORRV8HpZy5OMqMVH7xqwkLcvTbo
uFKE99LWQ8PDdBFQiO6fUhRRLoagFcDT : RGa8MqS4NZtAbWM8Voloi9kSVPg5AoKc5kySZxoYtpkOFgHU
NZqgHW5oOkxHxc5OgVXkJGQ0Kus3rOjz : QQsfDh5Q7S1BB8UHiB0Ni3okKn8lEEbeDx1k4k2OjT2jWuzr

Let me know if you see any security issues with the above code, I admit that I don’t fully understand the gmp_ functions.

Thomas Hunter II

Thomas is the author of Advanced Microservices and a prolific public speaker with a passion for reducing complex problems into simple language and diagrams. His career includes working at Fortune 50's in the Midwest, co-founding a successful startup, and everything in between.