Code archives/Networking/cd-key online verification

This code has been declared by its author to be Public Domain code.

Download source code

cd-key online verification by Arska2012
Here is simple and secure way to check if cd-key is valid.

Why it's secure?
Program doesn't send CD-key anywhere. We send MD5 hash which cannot be returned back to CD-key. Even CD-key check server doesn't know users keygen. Server knows only list of valid MD5 hashes. If MD5 hash list leaks. No problem. Hashes are useless. :)

Here is how it works:
1. User gives cd-key.
2. Program turns cd-key into MD5 hash
3. Program sends MD5 hash to server
4. PHP script checks if cd-key is valid
5. PHP script outputs result
6. Program read result.

What do you need?

Blitzmax side:
cd-key

PHP side:
List of all cd-keys MD5 hashes


You propably need keygen and MD5 generator. You can find my generator from my website at 'products' section:
http://arska134.viuhka.fi/

I'll post PHP side comments below.

Edit: Updated description
Strict


Local keygen:String = "6664-4027-4945-5115-5472"

Local keygenMD5hash:String = Trim(MD5(keygen))

Print "Sending MD5 Hash to server: "+keygenMD5hash

Local stream:TStream = ReadStream("http::example.com/cdkeycheck.php?hash="+keygenMD5hash)


If Not stream Then
	Print "Error occurred!"
	Print "- Check your internet connection."
	Print "- CD-key check server maybe down. Try again later."
	End
EndIf

While Not stream.Eof()

	Local response:String = stream.ReadLine()

	If response = keygenMD5hash Then Print "You are authorized!"
	If response <> keygenMD5hash Then Print "Invalid CD-key"
	
Wend



stream.close()


Function MD5$(in$)
  Local h0 = $67452301, h1 = $EFCDAB89, h2 = $98BADCFE, h3 = $10325476
    
  Local r[] = [7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,..
                5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,..
                4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,..
                6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21]
                
  Local k[] = [$D76AA478, $E8C7B756, $242070DB, $C1BDCEEE, $F57C0FAF, $4787C62A,..
                $A8304613, $FD469501, $698098D8, $8B44F7AF, $FFFF5BB1, $895CD7BE,..
                $6B901122, $FD987193, $A679438E, $49B40821, $F61E2562, $C040B340,..
                $265E5A51, $E9B6C7AA, $D62F105D, $02441453, $D8A1E681, $E7D3FBC8,..
                $21E1CDE6, $C33707D6, $F4D50D87, $455A14ED, $A9E3E905, $FCEFA3F8,..
                $676F02D9, $8D2A4C8A, $FFFA3942, $8771F681, $6D9D6122, $FDE5380C,..
                $A4BEEA44, $4BDECFA9, $F6BB4B60, $BEBFBC70, $289B7EC6, $EAA127FA,..
                $D4EF3085, $04881D05, $D9D4D039, $E6DB99E5, $1FA27CF8, $C4AC5665,..
                $F4292244, $432AFF97, $AB9423A7, $FC93A039, $655B59C3, $8F0CCC92,..
                $FFEFF47D, $85845DD1, $6FA87E4F, $FE2CE6E0, $A3014314, $4E0811A1,..
                $F7537E82, $BD3AF235, $2AD7D2BB, $EB86D391]
                
  Local intCount = (((in$.length + 8) Shr 6) + 1) Shl 4
  Local data[intCount]
  
  For Local c=0 Until in$.length
    data[c Shr 2] = data[c Shr 2] | ((in$[c] & $FF) Shl ((c & 3) Shl 3))
  Next
  data[in$.length Shr 2] = data[in$.length Shr 2] | ($80 Shl ((in$.length & 3) Shl 3)) 
  data[data.length - 2] = (Long(in$.length) * 8) & $FFFFFFFF
  data[data.length - 1] = (Long(in$.length) * 8) Shr 32
  
  For Local chunkStart=0 Until intCount Step 16
    Local a = h0, b = h1, c = h2, d = h3
        
    For Local i=0 To 15
      Local f = d ~ (b & (c ~ d))
      Local t = d
      
      d = c ; c = b
      b = Rol((a + f + k[i] + data[chunkStart + i]), r[i]) + b
      a = t
    Next
    
    For Local i=16 To 31
      Local f = c ~ (d & (b ~ c))
      Local t = d

      d = c ; c = b
      b = Rol((a + f + k[i] + data[chunkStart + (((5 * i) + 1) & 15)]), r[i]) + b
      a = t
    Next
    
    For Local i=32 To 47
      Local f = b ~ c ~ d
      Local t = d
      
      d = c ; c = b
      b = Rol((a + f + k[i] + data[chunkStart + (((3 * i) + 5) & 15)]), r[i]) + b
      a = t
    Next
    
    For Local i=48 To 63
      Local f = c ~ (b | ~d)
      Local t = d
      
      d = c ; c = b
      b = Rol((a + f + k[i] + data[chunkStart + ((7 * i) & 15)]), r[i]) + b
      a = t
    Next
    
    h0 :+ a ; h1 :+ b
    h2 :+ c ; h3 :+ d
  Next
  
  Return (LEHex(h0) + LEHex(h1) + LEHex(h2) + LEHex(h3)).ToLower()  
End Function

Function SHA1$(in$)
  Local h0 = $67452301, h1 = $EFCDAB89, h2 = $98BADCFE, h3 = $10325476, h4 = $C3D2E1F0
  
  Local intCount = (((in$.length + 8) Shr 6) + 1) Shl 4
  Local data[intCount]
  
  For Local c=0 Until in$.length
    data[c Shr 2] = (data[c Shr 2] Shl 8) | (in$[c] & $FF)
  Next
  data[in$.length Shr 2] = ((data[in$.length Shr 2] Shl 8) | $80) Shl ((3 - (in$.length & 3)) Shl 3) 
  data[data.length - 2] = (Long(in$.length) * 8) Shr 32
  data[data.length - 1] = (Long(in$.length) * 8) & $FFFFFFFF
  
  For Local chunkStart=0 Until intCount Step 16
    Local a = h0, b = h1, c = h2, d = h3, e = h4

    Local w[] = data[chunkStart..chunkStart + 16]
    w = w[..80]
    
    For Local i=16 To 79
      w[i] = Rol(w[i - 3] ~ w[i - 8] ~ w[i - 14] ~ w[i - 16], 1)
    Next
    
    For Local i=0 To 19
      Local t = Rol(a, 5) + (d ~ (b & (c ~ d))) + e + $5A827999 + w[i]
      
      e = d ; d = c
      c = Rol(b, 30)
      b = a ; a = t
    Next
    
    For Local i=20 To 39
      Local t = Rol(a, 5) + (b ~ c ~ d) + e + $6ED9EBA1 + w[i]
      
      e = d ; d = c
      c = Rol(b, 30)
      b = a ; a = t
    Next
    
    For Local i=40 To 59
      Local t = Rol(a, 5) + ((b & c) | (d & (b | c))) + e + $8F1BBCDC + w[i]
      
      e = d ; d = c
      c = Rol(b, 30)
      b = a ; a = t
    Next

    For Local i=60 To 79
      Local t = Rol(a, 5) + (b ~ c ~ d) + e + $CA62C1D6 + w[i]
      
      e = d ; d = c
      c = Rol(b, 30)
      b = a ; a = t
    Next
    
    h0 :+ a ; h1 :+ b ; h2 :+ c
    h3 :+ d ; h4 :+ e
  Next
  
  Return (Hex(h0) + Hex(h1) + Hex(h2) + Hex(h3) + Hex(h4)).ToLower()  
End Function

Function SHA256$(in$)
  Local h0 = $6A09E667, h1 = $BB67AE85, h2 = $3C6EF372, h3 = $A54FF53A
  Local h4 = $510E527F, h5 = $9B05688C, h6 = $1F83D9AB, h7 = $5BE0CD19
  
  Local k[] = [$428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, $3956C25B, $59F111F1,..
                $923F82A4, $AB1C5ED5, $D807AA98, $12835B01, $243185BE, $550C7DC3,..
                $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, $E49B69C1, $EFBE4786,..
                $0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA,..
                $983E5152, $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147,..
                $06CA6351, $14292967, $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13,..
                $650A7354, $766A0ABB, $81C2C92E, $92722C85, $A2BFE8A1, $A81A664B,..
                $C24B8B70, $C76C51A3, $D192E819, $D6990624, $F40E3585, $106AA070,..
                $19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, $4ED8AA4A,..
                $5B9CCA4F, $682E6FF3, $748F82EE, $78A5636F, $84C87814, $8CC70208,..
                $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2]

  Local intCount = (((in$.length + 8) Shr 6) + 1) Shl 4
  Local data[intCount]
  
  For Local c=0 Until in$.length
    data[c Shr 2] = (data[c Shr 2] Shl 8) | (in$[c] & $FF)
  Next
  data[in$.length Shr 2] = ((data[in$.length Shr 2] Shl 8) | $80) Shl ((3 - (in$.length & 3)) Shl 3) 
  data[data.length - 2] = (Long(in$.length) * 8) Shr 32
  data[data.length - 1] = (Long(in$.length) * 8) & $FFFFFFFF
  
  For Local chunkStart=0 Until intCount Step 16
    Local a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7

    Local w[] = data[chunkStart..chunkStart + 16]
    w = w[..64]
    
    For Local i=16 To 63
      w[i] = w[i - 16] + (Ror(w[i - 15], 7) ~ Ror(w[i - 15], 18) ~ (w[i - 15] Shr 3))..
            + w[i - 7] + (Ror(w[i - 2], 17) ~ Ror(w[i - 2], 19) ~ (w[i - 2] Shr 10))
    Next
    
    For Local i=0 To 63
      Local t0 = (Ror(a, 2) ~ Ror(a, 13) ~ Ror(a, 22)) + ((a & b) | (b & c) | (c & a))
      Local t1 = h + (Ror(e, 6) ~ Ror(e, 11) ~ Ror(e, 25)) + ((e & f) | (~e & g)) + k[i] + w[i]
      
      h = g ; g = f ; f = e ; e = d + t1
      d = c ; c = b ; b = a ;  a = t0 + t1  
    Next
    
    h0 :+ a ; h1 :+ b ; h2 :+ c ; h3 :+ d
    h4 :+ e ; h5 :+ f ; h6 :+ g ; h7 :+ h
  Next
  
  Return (Hex(h0) + Hex(h1) + Hex(h2) + Hex(h3) + Hex(h4) + Hex(h5) + Hex(h6) + Hex(h7)).ToLower()  
End Function

Function Rol(val, shift)
  Return (val Shl shift) | (val Shr (32 - shift))
End Function

Function Ror(val, shift)
  Return (val Shr shift) | (val Shl (32 - shift))
End Function

Function LEHex$(val)
  Local out$ = Hex(val)
  
  Return out$[6..8] + out$[4..6] + out$[2..4] + out$[0..2]
End Function

Comments

Arska2012
PHP side:
<?php

$clientMD5Hash = trim($_GET['hash']);

$fh = fopen("data/MD5.txt", "r");

while(!feof($fh)) { 

$lines = trim(fgets($fh));


if ($lines == $clientMD5Hash) {
     echo $lines;
     break;

} else {
// echo $clientMD5Hash." is invalid MD5 hash";
}


}



fclose($fh);

?>


So this script should return MD5 hash to program if it's valid.


Silver_Knee2016
While this is not a bad Idea, i want to point out a very easy way to crack that:

Your can mimic cdkeycheck.php's behavior for "valid key" for every possible user input: You can wireshark the dns where your CD check is sent to and set it in the computer's /etc/hosts to 127.0.0.1. Then start a webserver that returns the key that was GET from cdkeycheck.php...

To stop this, you have to make your webserver special, so your program only trusts the "valid key" if it is coming from your server. This works best if the server is also somehow needed in the game. It then gets more and more difficult for crackers to really mimic all of the server's aspects that are only there for DRM without cutting you off completely from the server.


Guy Fawkes2016
Or you can use Vernam Cipher


Code Archives Forum