FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Quick Software Protection
Posts: 933
Joined: Sun Oct 09, 2005 01:05 PM

Quick Software Protection

Posted: Sat May 30, 2009 12:31 PM
Hi,

Some time ago, I wrote a few functions to provide a software "key" to help protect my software.

Looks like there was a small bug so I am posting it again.

The code above the "//////////////////////////////" is just to show how to use my functions, the stuff below are the functions.

I hope it can help others ... Enjoy

Code (fw): Select all Collapse
/* In the examples below we will use the following walues for the parameters:
    nKey = 123 
    nLicense = 5
    nSerial = 1221404635   //from my system
    cKey = 403-57723-2677-6150 //from my system
*/


#include "FiveWin.ch"

Static cStored, cKey, nSerial, oKeyGen
Function Main()
    Local oWnd, oBtn
    
    Define Window oWnd
        @ 2,1 Say "NSerialHD on this system = "+STR( nSerialHD() )
        @ 3,1 Say "cKey on this system =      "+ MakeKey(123,5) 
        @ 5,1 BUTTON oBtn PROMPT "Test MakeKey( nKey, nLicense )" SIZE 300,25 Action TMakeKey1() 
        @ 7,1 BUTTON oBtn PROMPT "Test MakeKey()" SIZE 300,25 Action TMakeKey2()     
        @ 9,1 BUTTON oBtn PROMPT "Test VerifyKey( nKey, nLicense, cKey )" SIZE 300,25  Action TVerifyKey()      
        @ 11,1 BUTTON oBtn PROMPT "Test GetLicense( nKey, cStored )" SIZE 300,25  Action TGetLicense()      
        
    Activate Window oWnd
Return Nil
        
        
        
Function TMakeKey1()
/*  Test Makekey() and provide nKey and nLicense
    This is used on the computer you are making a key for.
    MakeKey( nKey, nLicense ) will return the cKey for the computer it is run on
    nKey is your secret key
    nLicense is the number of licenses you are giving to end user (it is only a number
    you must do the code to limit your app)
*/

   //below we will use 123 as our secret key and give 5 licenses
   //what is displayed in the message box is the users software key
    Msginfo(  MakeKey( 123 , 5 ) )   
Return Nil

Function TMakeKey2()
/*  Test Makekey() without and parameters
    This is used on any computer. 
    It will ask for nKey (your secret key), nSerial (nSerialHD() from the users computer) and
    nLicense (number of licenses you are giving to end user (it is only a number you must do 
    the code to limit your app)
    
    MakeKey() will return the cKey 
*/
    MakeKey()
Return Nil
    
Function TVerifyKey()
/*  VerifyKey( nKey,nLicense, cKey) returns a logical T or F
    nKey is your secret key
    nLicense is the number of licenses you are giving to end user (it is only a number
    you must do the code to limit your app)
   cKey is the users software key (See MakeKey() )
*/      

   If VerifyKey( 123, 5, "403-57723-2677-6150")
        MsgInfo( "Key is good" )
    Else
        MsgInfo( "Key is bad" ) 
    Endif

Return Nil

Function TGetLicense()
/* GetLicense( nKey, cStored )
    nKey is your secret key
    cStored is the users software key (same as cKey...see MakeKey() )
    Returns nLicense
*/
    MsgInfo( GetLicense( 123, "403-57723-2677-6150" ) )
Return Nil



///////////////////////////////////////////////////////////////////////////////////////


Function MakeKey(nKey,nLicense,lGetSecretKey, nSerial2)
   Local nTotal1:=0, nTotal2:=1,nTotal3:=0
   Local cDigit, i, lVisable:=.f.
   Local cHash1:=0, cHash2:=0, cHash3:=0, cHash4:=0
   Local cKey:=""
   Local nCount:=0
   Local nSerial:=nSerialHD(), oClp

   IF Empty(lGetSecretKey)
      lGetSecretKey := .f.
   ELSE
      nSerial := nSerial2
   ENDIF

   if Empty(nLicense)
      nLicense:=1
   endif

   if Empty(nKey)
      lVisable:=.t.
      nKey:=1
      nSerial:=0
      MsgGet("Key Generator","Enter Key: ",@nKey)
      MsgGet("Key Generator","Enter Serial Number: ",@nSerial)
      MsgGet("Key Generator","Number of Licenses: ",@nLicense)
   endif
   nCount:=len(alltrim(str(nSerial)))
   For i = 1 to nCount+1
       cDigit := SubStr( alltrim(str(nSerial)) ,i,1)
       nTotal1:=nTotal1+val(cDigit)
       if val(cDigit)<>0
          nTotal2:=nTotal2*val(cDigit)
       endif
       nTotal3:=nTotal3+(val(cDigit)*nCount)
   Next
   cHash1:=alltrim(str(nTotal1*nCount+nKey))
   cHash2:=alltrim(str(nTotal2*nCount+nKey))
   cHash3:=alltrim(str(nTotal3*nCount-nKey))
   cHash4:=alltrim(str(nLicense*nCount*nKey))

   cKey:= cHash1+"-"+cHash2+"-"+cHash3+"-"+cHash4
   
   IF lVisable
      MsgInfo("Serial Number: "+str(nSerial)+CRLF+"Key: "+cKey,"Key Generator")
      Define Window oKeyGen FROM 0,0 to 0,0
      Define CLIPBOARD oClp of oKeyGen
      Activate CLIPBOARD oClp
      oClp:SetText("Serial Number: "+str(nSerial)+CRLF+"Key: "+cKey+CRLF+"Licenses: "+str(nLicense))
      MsgInfo("The KEY has been copied to the clipboard")
      Activate Window oKeyGen on init oKeyGen:End()
   Endif
Return cKey



Function VerifyKey(nKey,nLicense,cStored)
   If Empty(nKey) .or. Empty(cStored)
      MsgInfo("A value is missing for VerifyKey()","KeyGen Error")
      Return .f.
   endif
   If MakeKey(nKey,GetLicense(nKey,cStored)) = cStored
      Return .t.
   else
      Return .f.
   endif
return nil
   
Function GetLicense(nKey,cStored)
   Local nLicense, i, j:=0, cHash4:="", nCount
   If Empty(nKey) .or. Empty(cStored)
      MsgInfo("A value is missing for GetLicense()","KeyGen Error")
      Return Nil
   endif

   nCount:=Len(alltrim(cStored))
   for i = 1 to nCount
       if substr(cStored,i,1)="-"
          j=j+1
       endif
       if j=3
           if substr(cStored,i,1)<>"-"           
             cHash4:=cHash4+substr(cStored,i,1)
           endif
       endif
   next
   nLicense:=val(cHash4)/nkey/ ( len( alltrim( STR( nSerialHD() ))))
return nLicense


Function GetSecretKey( nSerial, cKey )
   Local cSecret
   if empty(nSerial)
      MsgInfo("You MUST supply a Hard Drive Serial Number","ERROR")
      Quit
   ENDIF
   if empty(cKey)
      MsgInfo("You MUST supply a Key [ made by MakeKey() ]","ERROR")
      Quit
   ENDIF

   DEFINE WINDOW oKeyGen FROM 0,0 to 5,35 TITLE "Key Generator"
   ACTIVATE WINDOW oKeyGen on INIT cSecret:=DoSecret( nSerial, cKey )
Return cSecret

Function DoSecret( nSerial, cKey )
   Local nSecret := 0, lSearching := .t., nCount, i:=0, j
   Local cGetKey, cTempKey:="", cTemp:=""
   Local cHash1:="", cHash2:="", cHash3:="", cHash4:=""
   Local cGetHash1:="", cGetHash2:="", cGetHash3:="", cGetHash4:=""
   Local oSay

   IF ! MsgYesNo("This may take a LONG TIME to run, Continue?","Find Secret Key")
      Quit
   ENDIF

   FOR j = 1 to len(trim(cKey))
      i++
      cTemp := SUBSTR( cKey, i, 1 )
      cTempKey = cTempKey + cTemp
      IF cTemp = "-"
         if EMPTY( cHash1 )
            cHash1:=Left( cTempKey,len( trim( cTempKey ))-1 )
            cTempKey:=""
            loop
         endif
         if EMPTY( cHash2 )
            cHash2:=Left( cTempKey,len( trim( cTempKey ))-1 )
            cTempKey:=""
            loop
         endif
         if EMPTY( cHash3 )
            cHash3:=Left( cTempKey,len( trim( cTempKey ))-1 )
            cTempKey:=""
            loop
         endif
      ENDIF
   NEXT

   lSearching := .t.

   DO WHILE lSearching
      i++
      @ 1,1 SAY "Working..."+STR(i) of oKeyGen COLOR "R+/W" 
      SysWait()
      cGetKey := MakeKey( i, 5, .t., nSerial )
      cGetHash1:=left(cGetKey,len(cHash1))
      cGetHash2:=substr(cGetKey,len(alltrim(cHash1))+2,len(alltrim(cHash2)))
      cGetHash3:=substr(cGetKey,len(alltrim(cHash1))+len(alltrim(cHash2))+3,len(alltrim(cHash3)))

      if cHash1=cGetHash1 .and. cHash2=cGetHash2 .and. cHash3=cGetHash3
         @ 1,1 SAY "Done....................." of oKeyGen COLOR "R/w" 
         SysWait()
         MsgInfo("You Secret Key is: "+STR(i),"Secret Key Finder")
         oKeyGen:End()
         lSearching := .f.
      endif
   ENDDO
Return i
Thanks,

Jeff Barnes



(FWH 16.11, xHarbour 1.2.3, Bcc730)
Posts: 3107
Joined: Fri Oct 07, 2005 06:28 PM

Re: Quick Software Protection

Posted: Sun May 31, 2009 09:21 AM

Thanks jeff
It run ok

Best Regards, Saludos



Falconi Silvio

Continue the discussion