Code archives/Networking/cd-key online verification
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
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
| ||
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. |
| ||
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. |
| ||
Or you can use Vernam Cipher |
Code Archives Forum