Clan x86

Technical (Development, Security, etc.) => General Programming => Tutorials, References, and Examples => Topic started by: Joe on November 02, 2007, 11:02:26 pm

Title: PHP: Domain-based licensing
Post by: Joe on November 02, 2007, 11:02:26 pm
This is a piece of code I found when doing some fall cleaning that I wrote for RAC a while back, but my bid wasn't taken. This is meant to create a "code" based on a domain, and can be verified by checking the domain against the code.

Code: [Select]
<?PHP

//============================================================
//#region TESTING CODE
echo "Domain:      www.google.com<br />";
echo "Code: " .    makeCode("www.google.com") . "<br />";
echo "Success: " . (bool) verifyCode("www.google.com", makeCode("www.google.com"));
echo "<br />";
echo "<br />";
echo "Domain:      www.yahoo.com<br />";
echo "Code: " .    makeCode("www.yahoo.com") . "<br />";
echo "Success: " . (bool) verifyCode("www.yahoo.com",  makeCode("www.yahoo.com"));
echo "<br />";
echo "<br />";
echo "Domain:      www.amazon.com<br />";
echo "Code: " .    makeCode("www.amazon.com") . "<br />";
echo "Success: " . (bool) verifyCode("www.amazon.com", makeCode("www.amazon.com"));
echo "<br />";
echo "<br />";
//#endregion TESTING CODE
//============================================================

function makeCode($arg_domain)
{
$hash = $arg_domain; // Bring in the original string

$hash = sha1($hash, true); // SHA-1 hash the whole string
$hash = hashChars($hash); // Hash it, character by character

$hash = md5($hash, true); // MD5 hash the whole string
$hash = hashChars($hash); // Hash it, character by character

$hash = md5($hash, false); // Hash it again, this time to text

$result = "";
for($i = 0; $i < 64 /* length of MD5 hash */; $i+=2) // This takes every fourth character
{ // from the string, and then makes
$result .= substr($hash, $i, 1); // that the result
}

return strtoupper($result); // This capitalizes the final result
}

function verifyCode($domain, $code)
{
return (makeCode($domain) == $code);
}

// ----------------------------------------------------
// The below code is called by the above two methods to
// provide various encryption techniques.
// ----------------------------------------------------

function hashChars($arg_data)
{
$result = "";
for($i = 0; $i < strlen($arg_data)-4; $i+=4)
{
$result .= substr(sha1(substr($arg_data, $i,   1), true), 1, 1);
$result .= substr(sha1(substr($arg_data, $i+1, 1), true), 1, 1);
$result .= substr(sha1(substr($arg_data, $i+2, 1), true), 1, 1);
$result .= substr(sha1(substr($arg_data, $i+3, 1), true), 1, 1);
}
return $result;
}
?>
Title: Re: PHP: Domain-based licensing
Post by: Camel on November 05, 2007, 12:24:38 pm
Why not just use the domain name as the "code"?

The use of your verifyCode() function in the header is pointless; a result of false would disprove the reflexive axiom, which just won't happen.
Title: Re: PHP: Domain-based licensing
Post by: Joe on November 07, 2007, 12:04:42 am
Why not just use the domain name as the "code"?

This was for a client who wanted it to be difficult to spoof your code. Being server side, it can't be reverse-engineered (disclaimer: easily), and you wouldn't necessarily have to have your domain registered.

The use of your verifyCode() function in the header is pointless; a result of false would disprove the reflexive axiom, which just won't happen.

What's a reflexive axiom? It was just to demonstrate that the same result is produced each time, by calling makeCode twice and comparing the results.
Title: Re: PHP: Domain-based licensing
Post by: Camel on November 07, 2007, 12:42:33 am
What's a reflexive axiom?
[tex]x = x[/tex]

It was just to demonstrate that the same result is produced each time, by calling makeCode twice and comparing the results.
In C, there is a little known keyword (whose name I happen to forget) to indicate that a function's output is defined explicitly by its inputs, and that the machine's state is unchanged by the function call. In that way, the compiler knows not to generate a call to the function if the parameters are constant, and it knows that if certain parameters are constant, it can inline the function for a benefit much greater than a function that doesn't have this property.

Modern C compilers are intelligent enough to work without the keyword as a hint, because they can analyze the function to determine whether it has these properties. SHA1, MD5, and your function are members of this set of functions, because their input is 1:1 with their output.