Code archives/Algorithms/Key Generator

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

Download source code

Key Generator by Rob Farley2004
Put in a name... Out comes a key...

The idea of this is that you can release a complete piece of software and have bits disabled until people type in their name / email and a key.

So they email you and say, "Here have lots of cash", you say, "OK, here's the key". Hey presto, they have fully featured software and you have a lump of cash... well... that's the theory!

Very basic, but does the job. I'm sure if people really wanted to they could reverse engineer this but I think it's good enough for most people.

Check out the comments throughout the code to explain how to make it unique to you.

You're free to use this as you want, apart from ripping it off and claiming it to be your own work, that's a bit rude. If you use this in your own code credit would be nice, money would be better (donate button on my site), or at least an email to say thanks!

Feel free to improve upon this, but make sure you release it back to the community.
; KeyGen
; 2004 MentalIllusion.co.uk
; web: http://www.mentalillusion.co.uk
; email: rob@mentalillusion.co.uk

; This is a key generator for any blitzy thing you want
; include it in your main programs to unlock bits of code.

; The usage is pretty straight forward, key$ = keygen("Name or whatever")
; So you'll need to keep a version for yourself for sending keys to people!



name$ = "rob@mentalillusion.co.uk"

key$ = keygen(name)
Print name
Print key
WaitKey


Function keygen$(name$)

	; change v$ to as many or few random or unrandom letters, numbers, characters whatever
	; this is what the key is going to be made out of
	; You can have duplicates all over the place if you want, it's up to you!
	; This is one part that will make your keys unique to other people using this program
	; e.g. v$="I1D9U0AJ5PFWIN1TR3EKLWZID42HU7KL8S6LTBN9VMCXOF6T46GY3JHIE9T7VTLFDEQ3Y38P"

	v$ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

	tname$ = name$

	; make name longer if necessary
	; again adjust this to make your keys unique

	namel = 20
	Repeat
		If Len(tname) <= namel
			temp$ = ""
			For n = 1 To Len(tname)
				temp = temp + Chr(Asc(Mid(tname, n, 1)) + 1)
			Next
			tname = tname + temp
		EndIf
	Until Len(tname) > namel

	; this bit makes sure that you don't get any obvious repetitions over the 20 character key
	For n = 5 To 100 Step 5
		If Len(tname) = n Then tname = tname + "~"
	Next

	; create encrypt string
	encrypt$ = ""
	For n = 0 To 19
		encrypt = encrypt + Chr(1)
	Next
	ee = 1

	; over load encrypt 30 times
	; change this to make your keys unique further

	For l = 1 To 30

		For n = 1 To Len(tname)
			a = Asc(Mid(tname, n, 1))
			a = a - 32

			temp$ = ""

			For nn = 1 To 20
				tl = Asc(Mid(encrypt, nn, 1))
				If nn = ee Then temp = temp + Chr(tl + a Mod 256)Else temp = temp + Chr(tl)
			Next
			encrypt = temp
			ee = ee + 1
			If ee = 20 Then ee = 1
		Next

	Next

	; suck out the key
	encrypted$ = ""
	For ee = 1 To 20
		e = Asc(Mid(encrypt, ee, 1))Mod Len(v)
		If e = 0 Then e = 1
		encrypted = encrypted + Mid(v, e, 1)
	Next

	; format the key with -'s
	encrypted = Mid(encrypted, 1, 5) + "-" + Mid(encrypted, 6, 5) + "-" + Mid(encrypted, 11, 5) + "-" + Mid(encrypted, 16, 5)

	; return the key
	Return encrypted

End Function

Comments

_PJ_2004
Just as a note, many commercial keygens avoid using 1,I,O,0 etc. because they can seem ambiguous when written down.


Rob Farley2004
Fair point, which is why you can choose exactly what characters are included in your key (v$).


puki2004
Good point "Malice" - shame it wasn't thought of when Blitz3D was intially launched - would have saved me grief.


eizdealer2004
Nice code, but whoever uses it should compress the .exe with UPX or something, because otherwise it would be very very easy to get the assembler code from the .exe and the whole algo as well.


Rook Zimbabwe2004
I wonder what BLITZhacker program would see!


Azathoth2004
How would you check if the key is valid?


Rob Farley2004
Eizdealer: You're probably right, however, I would suspect most people (if you're not asking for unreasonable cash) are not going to bother. Everything is hackable, it just depends on how much time you want to spend doing it.

Vowels: Use the same bit of code in the game/app. So when a person enters their email address and key, you run the code to see if the key matches what you'd expect it to be.


Ken Lynch2004
So when a person enters their email address and key, you run the code to see if the key matches what you'd expect it to be.


This means all you have to do to crack this is to monitor the program memory when you enter your email and you have a key generated, no need to know the algorithm. Any hacker could do that in minutes and it would probably be one of the first things they would try.


Rob Farley2004
Ken,

EVERYTHING is hackable. You're suggesting that you need to know when this bit of code gets run (which is inside information), you don't have to run it as soon as someone types in their email address, you could run it when they hit the register button or unlock button... or 12.58395 seconds after they hit the unlock button. I was merely making a suggestion of how this could be used.

This is free, and of course flawed. If you don't want to use it - don't. If you can improve upon it - do. If you can make useful suggestions - please do.

Also this would be used on maybe a £10 app or game, if you're planning on making something that is worth hacking then maybe you should use (and pay for) higher security.

Quite frankly I don't know why the &%$# I bother...


big10p2004
Gift. Horse. Mouth. Look. Don't. :)


podperson2004
If you use a key for shareware validation, I recommend that you use a checksum and ONLY check the checksum on entry.

E.g. you have a function that produces a randomish string given another string.

EncryptedString = SomeFunction(InputString)

InputString = RandomString + UserName
Key = RandomString + EncryptedString + Checksum

RandomString is there to allow you to sell more than one license to someone named John Smith. It also makes SomeFunction harder to reverse-engineer.

Checksum is there to perform a cheap check on an entered key. It will detect HONEST mistakes but not provide a simple point at which to (a) spike your code or (b) locate your encryption function and step through it.

Check the checksum on input, then check the actual key in your game's main event loop. It's MUCH harder for a cracker to spike your main event loop than to find the branch that checks your key and change one assembler instruction (BRANCH if equal vs. DONTBRANCH if equal).


Blitzogger2004
Or you could use Armadiilo from Silicon Realms to wrap and generate the keys for you. You can get it at http://www.siliconrealms.com.


Rook Zimbabwe2004
Or maybe some enterprising B3D user could create a DLL to do that and only charge 10-20$ US for it instead of $79US for Armadillo... I am cheap and sorry that I myself am not up to the task or I owuld!

-RZ


Filax2005
It is possible to make reverse engineering on this ?
find the string from the crypted string ?


Damien Sturdy2005
Why does it matter?

I wouldnt worry about it getting hacked if your games not *all that and more*. if it is, then you need higher security, and wont use this.

I can understand why rob flipped here, if this long after its release, people are still going on about hacking it.

You want something unhackable? Go pay the $$$$$. Then watch in amazement as some hacker 'tard hacks it. :P

Filax, You could reverse engineer alot of things, just depends how long you want to wait :)


John J.2005

Why does it matter?


It's always best to try to prevent hacking, to a reasonable extent.

Also, you could do something like this to prevent "code$" from being monitored:
;Checksum passed - check actual code
r = Rand(1, 50)
For i = 1 to 50
  If r = i Then code$ = GenerateCode(AccountName$) Else code$ = GenerateDummyCode(AccountName$)
  If code$ = typedcode$ Then Return ACCEPTED
Next
Return REJECTED

GenerateDummyCode() should be a fake algorithm that will generate codes that would NEVER be correct. This should not only prevent "code$" from being monitored, but hopefully should lead the hacker off the trail.

But what do I know? I'm no anti-hacker expert :)


tonyg2005
Works in Bmax as well just changing the comment character. Interestingly it produces a different serial number.
Very nice.


pexe2006
I converted this code to PHP, if you want to generate keys in your Website

<?
//So you'll need to keep a version for yourself for sending keys to people!
print keygen("pexe");

Function keygen ($name)   {

// change v$ to as many or few random or unrandom letters, numbers, characters whatever
// this is what the key is going to be made out of
// You can have duplicates all over the place if you want, it's up to you!
// This is one part that will make your keys unique to other people using this program
// e.g. v$="I1D9U0AJ5PFWIN1TR3EKLWZID42HU7KL8S6LTBN9VMCXOF6T46GY3JHIE9T7VTLFDEQ3Y38P"


$v = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

$tname = $name;

// make name longer if necessary
// again adjust this to make your keys unique

$namel = 20;
do {

If (strlen($tname) <= $namel) {
$temp = "";
For ($n=1; $n<=strlen($tname); $n++) {
$temp = $temp . chr(ord(substr($tname, $n-1, 1)) + 1);
}
$tname = $tname . $temp;
}

}
while (strlen($tname) <= $namel);



// this bit makes sure that you don't get any obvious repetitions over the 20 character key
For ($n = 5; $n <= 100; $n+=5) {
If (strlen($tname) == $n) { $tname = $tname . "~"; }
}


// create encrypt string
$encrypt = "";
for ($n = 0; $n <= 19; $n++) {
$encrypt = $encrypt . Chr(1);
}
$ee = 1;

// over load encrypt 30 times
// change this to make your keys unique further

for ($l = 1; $l<=30; $l++) {

For ($n = 1; $n<=strlen($tname); $n++) {
$a = Ord(SubStr($tname, $n-1, 1));
$a = $a - 32;

$temp = "";

For ($nn = 1; $nn<=20; $nn++) {
$tl = Ord(Substr($encrypt, $nn-1, 1));
If ($nn == $ee) {
$temp = $temp . Chr($tl + $a % 256);
}Else{
$temp = $temp . Chr($tl);
}
}

$encrypt = $temp;
$ee = $ee + 1;
If ($ee == 20) { $ee = 1; }
}

}

// suck out the key
$encrypted = "";
For ($ee = 1; $ee<=20; $ee++) {
$e = Ord(Substr($encrypt, $ee-1, 1))% strlen($v);
If ($e == 0) { $e = 1; }
$encrypted = $encrypted . substr($v, $e-1, 1);
}

// format the key with -'s
$encrypted = substr($encrypted, 1-1, 5) . "-" . substr($encrypted, 6-1, 5) . "-" . substr($encrypted, 11-1, 5) . "-" . substr($encrypted, 16-1, 5);

// return the key
Return $encrypted;

}
?>

:)


xlsior2006
Nice!


Rook Zimbabwe2006
This is how I have used this program:

I use this program in concert with TERAPACK
http://www.blitzbasic.com/toolbox/toolbox.php?tool=30

TERAPACK has the ability to make new packs from inside your program...

I make a file that has several useless things in it AND a number. File looks something like this (simplified version)

[Sharedata]
001=26
002=101

[Audio]
Music=E090

[RegInfo]
001=UNREGISTERED
002=you@...
003=1324-4657-7890-ABCDEF


Note you can also save setting information in this pack. The important thing is ShareData 001 , RegInfo 002 and 003.

In the unregistered version of my game if the email address in 002 and the reg code in 003 do not match the program diminishes the number in ShareData 001 by 1. If that number = 0 or less 0 program no runs.

Heres basically how:
1. Program open on a selection menu.
2. Program unpacks this file to the hard drive where the game is.
3. Program checks email address and code.
A> If code matches program displays REGISTERED TO whoever@...
B> If code does not match program dimished number in ShareData001 by 1. packs the file and resaves it.

I use a seperate program to register the main program.

Simple.


Pete Rigz2009
A quick conversion to Blitzmax module. Generates the same codes as the original version (assuming you you use the same v$ value):

'KeyGen
'2004 MentalIllusion.co.uk
'web: http://www.mentalillusion.co.uk
'email: rob@...
'
'This is a key generator for any blitzy thing you want
'include it in your main programs to unlock bits of code.
'
'The usage is pretty straight forward, key$ = keygen("Name or whatever")
'So you'll need to keep a version for yourself for sending keys to people!

SuperStrict

Module rob.keygen
ModuleInfo "Author: Rob Farley"
ModuleInfo "Conversion to Blitzmax: Peter Rigby"
ModuleInfo "Public Domain"
ModuleInfo "Purpose: Generate keys for the purpose of registering software"

rem
	bbdoc: Generates a key based on the name you pass it
	about: This function generates a key from whatever name string you pass to it. Pass a different v string to make it unique to you.
	returns: The generated key string.
end rem
Function keygen:String(name:String, v:String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")

'	change v$ to as many or few random or unrandom letters, numbers, characters whatever
'	this is what the key is going to be made out of
'	You can have duplicates all over the place if you want, it's up to you!
'	This is one part that will make your keys unique to other people using this program
'	e.g. v$="I1D9U0AJ5PFWIN1TR3EKLWZID42HU7KL8S6LTBN9VMCXOF6T46GY3JHIE9T7VTLFDEQ3Y38P"

	Local tname:String = name:String

'	make name longer if necessary
'	again adjust this to make your keys unique

	Local namel:Int = 20
	Local temp:String = ""
	
	Repeat
		If Len(tname) <= namel
			temp = ""
			For Local n:Int = 0 To Len(tname) - 1
				temp = temp + Chr(tname[n] + 1)
			Next
			tname = tname + temp
		EndIf
	Until Len(tname) > namel

'	this bit makes sure that you don't get any obvious repetitions over the 20 character key
	For Local n:Int = 5 To 100 Step 5
		If Len(tname) = n Then tname = tname + "~~"
	Next

'	create encrypt string
	Local encrypt:String = ""
	For Local n:Int = 0 To 19
		encrypt = encrypt + Chr(1)
	Next
	
	Local ee:Int
'	over load encrypt 30 times
'	change this to make your keys unique further
	Local a:Int
	Local tl:Int
	For Local l:Int = 1 To 30
		For Local n:Int = 0 To Len(tname) - 1
		
			a = tname[n]
			a = a - 32
			temp = ""

			For Local nn:Int = 0 To 19
				tl = encrypt[nn]
				If nn = ee Then temp = temp + Chr(tl + a Mod 256)Else temp = temp + Chr(tl)
			Next
			encrypt = temp
			ee = ee + 1
			If ee = 19 Then ee = 0
			
		Next
	Next

'	suck out the key
	Local encrypted:String = ""
	Local e:Int
	For Local ee:Int = 0 To 19
		e = encrypt[ee] Mod Len(v) - 1
		If e = -1 Then e = 0
		encrypted = encrypted + Chr(v[e])
	Next

'	format the key with -'s
	encrypted = encrypted[..5] + "-" + encrypted[5..10] + "-" + encrypted[10..15] + "-" + encrypted[15..20]

'	return the key
	Return encrypted

End Function



Code Archives Forum