Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need to generate a license key 1

Status
Not open for further replies.

tanveerhabib

Programmer
Dec 8, 2015
27
PK
Hello I have an application built in VFP which generates user ID from computer hardware. My question is how can I create a license generator for putting a valid license in the software. thank.s
 
How about using something third party? Generating keys is easy, can be as simple as generating a random number, the verification is the hard problem. Typically a license server is involved, so you don't solve the license check within your application alone.

What do you really need? A product key checked during installation, typed in by the user? Or a license verified at each start without user intervention?

A simple idea: During registration and payment you add a user record at your site, eg with the userid you generated from hardware keys. At startup check, if that userid is found at your server and if so, the software was licensed and paid, a simple query would suffice and you could count starts and monitor an unusual start frequency, etc.

This can be extended in many ways to allow the user to change hardware by reauthenticating with his account not only by the hardware related userid, which may at some day change irreversible due to hardware failure or new pc, etc. So allow for a classical login by username/email and password to let them update their hardware related userid. This way the software can be transferred to other hardware and from then on only be used there.

Once your software is reverse engineered and the check is removed you don't know about it, but that's true for any licensing mechanism. If you want something working without maintaining a stable online database with near 100% uptime, then rather use some licensing SDK. Experts know better how to protect your software from illegal installations.

I think every decent developer knows something about retrieving hardware serial numbers, encrypting, hashing, random number generation etc, but that's just knowing several ingredients, not a recipe. At some day I might offer such a licensing service, because I have a few ideas and think about an app shop, but in he moment I'd leave that up to security experts even for me.

Bye, Olaf.
 
By the way, welcome to the Foxpro forum as well as to tek-tips.

Bye, Olaf.
 

I have this code in place in which text4 has value experts travels and text2 has value 510 5716 0192

can you tell me how the actidtran and entchkdigit keys will be generated in this scenerio. what will be the keys I am confused...




addnewuser = ALLTRIM(thisform.text4.value)
idtran = ALLTRIM(STR(thisform.text2.value, 19, 0))
idtran = CHRTRAN(idtran, '1234567890', 'ANCDEFSHTZ')
idtran = ALLTRIM(idtran)
widchkdigit = VAL(CHRTRAN(idtran, 'ANCDEFSHTZ', '1234567890'))+999
idchkdigit = ALLTRIM(STR(widchkdigit*0.621 , 19, 0))
idchkdigit1 = ALLTRIM(STR(widchkdigit*0.799 , 19, 0))
lendeg1 = LEN(idchkdigit1)
lendeg2 = LEN(idchkdigit)
idchkdigit1 = SUBSTR(idchkdigit1, lendeg1-3, 4)
idchkdigit = SUBSTR(idchkdigit, lendeg2-3, 4)
idchkdigit1 = INT(VAL(idchkdigit1))
idchkdigit = INT(VAL(idchkdigit))
entchkdigit = thisform.text1.value
actidtran = thisform.text3.value
IF .NOT. actidtran=idchkdigit1
MESSAGEBOX('Wrong Verify Digit-1 entered', 64, '')
thisform.text3.value = 0
thisform.text3.setfocus
RETURN
ENDIF
IF .NOT. entchkdigit=idchkdigit
MESSAGEBOX('Wrong Verify Digit-2 entered', 64, '')
thisform.text1.value = 0
thisform.text1.setfocus
RETURN
ENDIF
SET LIBRARY TO MD5.FLL
INSERT INTO ufile (uname, uencname, hardid, compid) VALUES (addnewuser, md5hash("IP"+ALLTRIM(addnewuser)), md5hash(ALLTRIM(ghardid)), ALLTRIM(ghardid))
SELECT ufile
GOTO TOP
newno = 1
DO WHILE .NOT. EOF()
REPLACE sno WITH newno
newno = newno+1
SKIP
ENDDO
GOTO TOP
thisform.grid1.refresh
thisform.grid1.setfocus
 
In this code actidtran and entchkdigit are not computed, but taken from text1 and 3:

entchkdigit = thisform.text1.value
actidtran = thisform.text3.value

You're not even close to stating your problem.

Bye, Olaf.
 
I know that they are taken from text 4 and text 2

but I want to ask how the value is computed, for such license creation do i need a licence generating script also at my end ??? or how will we do that for license creation?
 
No, text 1 and 3, as shown.

text2 and 4 are taken here:
addnewuser = ALLTRIM(thisform.text4.value)
idtran = ALLTRIM(STR(thisform.text2.value, 19, 0))

Two comparisons are verifying the right key is entered: actidtran=idchkdigit1 and entchkdigit=idchkdigit
If the comparisons fail focus is set back to text1 and text3, where you need to enter the right Verify Digits.

Since you revealed the text2 value the calculation of idchkdigit1 and idchkdigit is straight forward from that. That's about no security at all unless the user can't decompile this. You obviously either don't understand your own code or more likely are not the developer of this.

You better start from scratch using an SDK and not something you don't comprehend. Plus you most probably revealed something you shouldn't have posted, three secrets: 1. user name 2. key 510 5716 0192, and 3. digit to char conversion via ANCDEFSHTZ, though this rather seems to be some obfuscation, as the transition is reversed two lines later. Are you trying to test us?

Besides this is only one part of the code you need, generating a user record. The hardware id ghardid is "falling from the sky", the g might indicate it's a global variable set somewhere else in code. It's also not used to verify your Verify Digits. So this code just checks you have the correct Verify Digits and then adds a record to ufile with username and hardware id, plus the two md5 hashes of both. The Verify Digits just keep a user from getting to the INSERT-SQL.

Bye, Olaf.
 
Hi,

I have this GUIDmaker function
Code:
**MakeGUID
Private pGuid
Local lcData1, lc1st4, lc2nd4, lc3rd4, lc4th4, lc5th4, lcData5, lc6th4, lc7th4, lcGuid

	Store "" To m.lc1st4, m.lc2nd4, m.lc3rd4, m.lc4th4, m.lc5th4, m.lc6th4, m.lc7th4, m.lcData1, m.lcData5
* -- declare external function
	Declare Integer CoCreateGuid In OLE32.Dll String @pGuid
* -- Initialize the buffer that will hold the GUID with nulls
	pGuid = Replicate(Chr(0),17)
* -- Call CoCreateGuid
	If CoCreateGuid(@m.pGuid) = 0   && success
* -- Store the first eight characters of the GUID in data1
		lcData1 = Right(Transform(strtolong(Left(m.pGuid,4)),"@0"),8)
		lc1st4 = Left(m.lcData1,4)
		lc2nd4 = Substr(m.lcData1,5,4)
* -- Store the first group of four characters of the GUID in data2
		lc3rd4 = Right(Transform(strtolong(Substr(m.pGuid,5,2)),"@0"),4)
* -- Store the second group of four characters of the GUID in data3
		lc4th4 = Right(Transform(strtolong(Substr(m.pGuid,7,2)),"@0"),4)
* -- Store the third group of four characters of the GUID in data4
		lc5th4 = Right(Transform(strtolong(Substr(m.pGuid,9,1)),"@0"),2) + Right(Transform(strtolong(Substr(m.pGuid,10,1)),"@0"),2)
* -- Initialize data5 to a null string
		lcData5 = ""
* -- Convert the final 12 characters of the GUID and store in data5
		For lnGuidLen = 1 To 6
			lcData5=m.lcData5+Right(Transform(strtolong(Substr(m.pGuid,10+m.lnGuidLen,1))),2)
		Endfor
* -- Check the length of data5. If less than 12, the final 12-len(data5) characters are '0'
		If Len(m.lcData5) < 12
			lcData5=m.lcData5+Replicate("0",12-Len(m.lcData5))
		Endif
		lc6th4 = Left(m.lcData5,4)
		lc7th4 = Substr(m.lcData5,5,4)
* -- Assemble the GUID into a string
		lcGuid  = m.lc1st4+"-"+m.lc2nd4+"-"+m.lc3rd4+"-"+m.lc4th4+"-"+m.lc5th4+"-"+m.lc6th4+"-"+m.lc7th4
	Endif

* -- Done with the call to CoCreateGuid, so clear the DLLs from memory
	Clear Dlls

	lcGuid = controldigit(m.lcGuid)

	Return m.lcGuid

Endfunc
*******************

Function strtolong
* -- Passed:  4-byte character string (lcLongstr) in low-high ASCII format
* -- Returns:  long integer value
* -- Example:
* -- m.longstr = "1111"
* -- m.longval = strtolong(m.longstr)
	Parameters lcLongstr

	Local lnByte As Number, ;
		lnRetval As Number

	lnRetval = 0
	For lnByte = 0 To 24 Step 8
		lnRetval = m.lnRetval + (Asc(m.lcLongstr) * (2^m.lnByte))
		lcLongstr = Right(m.lcLongstr, Len(m.lcLongstr) - 1)
	Next
	Return m.lnRetval
Endfunc

*!* 19-9-2015 10:45:03
*!* Purpose :  to implent a 37-check
*!*

Function controldigit
	Parameters tcGuid

	Local lcGuid As String, ;
		lcResult As String, ;
		lnDigit As Number, ;
		lnResult As Number, ;
		lnSum As Number

	lcGuid = Alltrim(m.tcGuid)+"-"
	lnSum = 0
	For lnDigit = 1 To Len(m.tcGuid)
		lnSum = m.lnSum + Asc(Substr(m.tcGuid,m.lnDigit,1))
	Endfor

	lnResult = Mod(m.lnSum,37)
	lcResult = Padl(Transform(m.lnResult),2,'0')

	Return m.lcGuid + Transform(m.lcResult)
Endfunc

Maybe this can be of any help in your case.

Regards,
Jockey(2)
P.S. I had only extended with a 37-digit check to simplify input-validation, the basis, GUID construction I found somewhere on the Internet, and shame on me, I did not keep track who is the author. Sorry for that.
 
Hi, I use license keys in all of my FoxPro based programs too, and what I do is use a MySQL Server that is hosted from my website, and a remote view. That way, you enter the key into a remote table that you have control of, this way you can bind user names (or in my case, company names) to the key, so they can't be shared.
 
I guess you are not the developer of this code. The values are 7100 and 1793. Try to follow what is advised above.
 
@NasibKalsi how have you calculated these two values please tell me. thanks.
 
tanveerhabib,

the code calculates these values. Quite a bad protection, if it's given away.

You can shorten 51057160192 to 7160192 and get the same results, and you can skip the two CHRTRANS, as I already said.
Both of this shows how weak this license key code is. It's more obfuscation than any real computation.

Bye, Olaf.


 
NasibKalsi and OlafDoschke,

suppose the ID is now 466 7413 7088 and is not 510 5716 0192 , so tell me what will be the verifty digit 1 and 2 now.
 
That is not cracking I want to understand the end result. If you can help me with understanding it. Thanks.
 
If you have the code (including the form), have foxpro and can't compute the checkdigits compared to text1 and text3, then you are in need of much more basic lessons about programming.

If I tell you the check digits for 466 7413 7088 you just know one more pair of check digits, that only helps you crack that specific code, not understand the mechanism.

Just to proof I can run this code with any ID: 322 1123 2324 will need check digits 5894 and 5425 (or vice versa) This is a deterministic calculation with the original value, two rather simple multiplications with 0.621 and 0.799, as is written in code. A substr of the result is taken.

I still recommend you use something from a vendor of licensing tools instead of rolling your own. It's too easy to decompile VFP and so you can easily compute the needed input.

The machnism TGrahmann suggests is easy to implement and unserstand, you just need a mysql database for saving licenses and checking them. You can make a connection via SSL so noone can easily hack your mysql database and add a user entry or license, you have this under control. Someone decompliing the code only knows you create GUIDS and store them in your database (I suggest at the same time someone activates and pays your application), that knowledge doen't help someone know which GUIDs are in your database and thus valid license keys, nor can he create license keys. Anyone can generate GUIDs, but only those stored in your database are valid. As simple as that.

Besides, that code is (as I already said, too) just half of what you need. This checks the user knows some (not so) secret check digits and then adds a user record. That just covers an initial start with license activation. It's totally unclear how the user record is valdated at next starts. There must be more code and if you don't understand that, because its not your own, then its better you restart and think about your needs and program something on your own, or take a ready to use third party component.

Bye, Olaf.
 
No one here need your personal information but talking about foxpro and decipher are two separate topics. Please try your best to follow what is already advised.

 
Can you provide a tutorial link from where I can easily learn programming in Foxpro
 
You want to learn foxpro now?

If you have the need to protect your own software you must have written a product worth protecting. If you did that without understanding what some basic functions like SUBSTR(), STR(), CHRTRAN(), ALLTRIM() etc do, then that makes you double suspicious as not being what you tell you are. Sorry, but that is quite ridiculous.

Bye, Olaf.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top