UniKey API Protection Solution

From SecuTech Wiki
Jump to: navigation, search


UniKey provides the most reliable hardware and software tools available in the market today. Both of the two ways of software protection prove to be effective. However, if you want to maximize your software protection, certain software protection strategies need to be implemented.

Challenges Facing Software Protection Companies

While software protection companies are trying their best to enhance the software protection level, software crackers get engaged in developing more sophisticated means of deconstructing software protection measures, in order to duplicate and distribute illegal copies of unlicensed software and to reverse engineer code so as to steal intellectual property. Once aware of the strategies of software crackers, software protection companies should implement the latest and strongest techniques for protecting software. In theory, there is no software protection that is absolutely uncrackable. However, if you constantly implement up-to-date strategies using the strongest software protection methods, you significantly decrease your vulnerability to such attacks.

Software Protection Concerns

There are two main methods of attacking protected applications that concern software publishers most.

  1. Simulating calls to the protection device.
  2. Simulating the software used by the manufacturer of the protection device.


Five Levels of Protection Guide

Since there are quite a few APIs available in the library of UniKey products, it proves quite difficult for vendors to be clear about the function of each API as well as which API should be applied for their specific purpose. In view of this, we decide to classify the APIs into five specific levels of protection so as to better serve our customers specific needs.

  1. The primitive level of protection
  2. The basic level of protection
  3. The average level of protection
  4. The professional level of protection
  5. The expert level of protection

The Advantages of Primitive Level of Protection

There are five APIs for a primitive level of protection:

long UniKey_Find(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_Find_Next(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_User_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2);

long UniKey_Vender_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2, WORD* pPassword3, WORD* pPassword4);

long UniKey_Logoff(WORD* pHandle);

Primitive level of protection can give you an easy and quick protection for your software. You do not need to write much code, and with just several lines of codes you will make your software protected. The main function of primitive-level protection APIs is letting you know your dongle's HID. And with this specific HID, you can easily know whether the dongle inserted is yours or not. In this part you will learn how to apply a primitive level of protection to your software. You can refer to the following picture to gain a quick understanding of it.

UniKey primitive software protection level

The method enables you to have quick and easy protection for your software. All you need to do is to call several functions in your project. The main usage of the API functions is offered below.

UniKey_Find: The first API you need to use is UniKey_Find It enables you to find your UniKey dongle and returns a number to show you the UniKey dongle’s HID (Hardware ID) as well. HID is important as it helps you decide whether or not a dongle belongs to you. When you use the UniKey_Find function it will return a code. The return code will show you whether or not the call is successful. For example, if it returns a value of 0, it means the UniKey_Find function ran fine. If it returns 200, it means it failed to find your dongle. At this time, you need to check whether or not your UniKey dongle is properly connected to your computer.

UniKey_Find_Next: The UniKey_Find_Next function is used for finding the next UniKey dongle. There are times when you want two or more UniKey dongles to work together. You need to call UniKey_Find first, and then call UniKey_Find_Next to find more UniKey dongles. As long as you find these UniKey dongles, you can let them work with your project.

UniKey_User_Logon: For the UniKey_User_Logon function, it is used when you want to log in to the UniKey dongle as an end user. When you implement this API, you can acquire the permission as a user to log in to the UniKey dongle. However your permissions are limited as a user. You can not implement APIs intended for the vendor. If you do call the APIs intended for the vendor, you will not get the results that you expect.

UniKey_Vender_Logon: For the UniKey_Vender_Logon function, it is used when you want to log in to the UniKey dongle as a vendor. It can not be used together with the UniKey_User_Logon. Only one can be formally implemented into your project. And if you use UniKey_Vender_Logon you will have to utilize vendor permissions. In vendor login mode, you can implement all the APIs.

UniKey_Logoff: For the UniKey_Logoff function, it is used when you want to log out of the UniKey dongle. When you finish operating the UniKey dongle, you can implement this API. It will let you log out of the UniKey dongle. After you call this function, you lose all permissions to use any other functions on the dongle.

The Advantages of Basic Level of Protection

There are nine APIs for a basic level of protection:

long UniKey_Find(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_Find_Next(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_User_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2);

long UniKey_Vender_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2, WORD* pPassword3, WORD* pPassword4);

long UniKey_Write_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Read_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Write_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Read_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Logoff(WORD* pHandle);

Besides the basic identification by HID, you can write your own phrases into the 4K memory of your UniKey dongle that will make a much safer protection for your software. If you prefer a serial number for your software, you can use the software ID provided by the UniKey library. It provides a quick way for you to assign a serial code for your UniKey dongle. In this part you will learn how to apply a basic protection to your software. You can refer to the following picture to gain a quick understanding of it.

UniKey basic software protection level

This method provides you with quick and easy protection for your software. All you need to do is to call several functions in your project. The main usage of the APIs is offered below.

UniKey_Write_Memory: For the UniKey_Write_Memory it is used when you want to write data into memory. This API needs to be called after you log in to a UniKey dongle. To write to the last 2KB memory (for 2048 – 4096), you need to verify all 4 passwords (vendor mode) to obtain full permissions to the dongle. UniKey_Read_Memory and UniKey_Write_Memory provide basic reading and writing functions to the dongle. You can store general information via such functions. And various levels of security can be applied too.

UniKey_Read_Memory: For the UniKey_Read_Memory you can call the API to read the contents of the memory. You need to log in to a UniKey dongle before calling the API. The size of the basic memory is up to 4KB. All memory is encrypted and CRC checked when communicating with applications. You only need to have user permissions to read the 4KB memory.

UniKey_Write_SoftID: For the UniKey_Write_SoftID you need to verify all 4 passwords (vendor mode) to write the software ID. When you call this API, if you set UniKey ID wrong, an error message will be returned.

UniKey_Read_SoftID: UniKey_Write_SoftID and UniKey_Read_SoftID provide a means to make a soft (write-able) ID for each software. You can write different software IDs for each UniKey and call UniKey_Read_SoftID to check if the software ID is correct.

The Advantages of Average Level of Protection

There are twelve APIs for an average level of protection:

<code> long UniKey_Find(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_Find_Next(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_User_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2);

long UniKey_Vender_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2, WORD* pPassword3, WORD* pPassword4);

long UniKey_Write_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Read_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Write_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Read_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Set_Module(WORD* pHandle, WORD* pModule, WORD* pValue, WORD* pDecrease);

long UniKey_Get_Module(WORD* pHandle, WORD* pModule, WORD* pValue);

long UniKey_Check_Module(WORD* pHandle, WORD* pModule, WORD* pValue, WORD* pDecrease);

long UniKey_Logoff(WORD* pHandle);

An average level of protection is famous for its license modules. Each license module has a value, if you want your software to run only five times, you can set it to 5, and then use a special UniKey API to decrease its value until its value reaches 0. Then, you will find you cannot access the software anymore. It is a good way to limit the number of executions of your software so that it is well protected. In this part you will learn how to apply an average level of protection to your software. You can refer to the following picture and gain a quick understanding of it.

UniKey average software protection level

The method enables you to have a quick and easy protection for your software. All you need to do is to call several functions in your project. The main usage of the APIs is offered below.

UniKey_Set_Module: For UniKey_Set_Module it is used when you want to set the module. After calling the API, you can write a value to a specific UniKey license module and set the Decrement attribute.

UniKey_Get_Module: For UniKey_Get_Module it is used when you want to get a value from a specific UniKey license module. You need to verify 2 passwords (user mode) to get a module value successfully.

UniKey_Check_Module: For UniKey_Check_Module it is used when you want to read attributes of a specific UniKey license module. A successful operation will result in *pValue having value based on the Validity (1 = license module value is not zero), and *pDecrease with the value from the Decrement attribute (1 = license module can be decreased). The value of a license module cannot be read out directly and it is invisible to end users. UniKey_Set_Module and UniKey_Check_Module provide an easy way to implement software limitation.

The Advantages of Professional Level of Protection

There are fifteen APIs for a professional level of protection:

long UniKey_Find(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_Find_Next(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_User_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2);

long UniKey_Vender_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2, WORD* pPassword3, WORD* pPassword4);

long UniKey_Write_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Read_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Write_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Read_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Set_Module(WORD* pHandle, WORD* pModule, WORD* pValue, WORD* pDecrease);

long UniKey_Get_Module(WORD* pHandle, WORD* pModule, WORD* pValue);

long UniKey_Check_Module(WORD* pHandle, WORD* pModule, WORD* pValue, WORD* pDecrease);

long UniKey_Encrypt(WORD* pHandle, DWORD* pBufferLength, DWORD* pKeyNumber, BYTE *pBuffer);

long UniKey_Decrypt(WORD* pHandle, DWORD* pBufferLength, DWORD* pKeyNumber, BYTE *pBuffer);

long UniKey_MD5(WORD* pHandle, DWORD* pBufferLength, BYTE *pBuffer);

long UniKey_Logoff(WORD* pHandle);

The Advantage of Professional Protection

A professional level of protection integrates encryption and decryption functions. You can use these two to encrypt or decrypt what you like, enhancing your security and making your software safer. If you use the encryption function, others will not even see the content. They can only see the cipher text, instead of the correct information. In this part you will learn how to apply a professional protection to your software. You can refer to the following picture and have a quick understanding of it.

UniKey professional software protection level

This method enables you to have quick and easy protection for your software. All you need to do is to call several functions in your project. The main usage of the APIs is offered below.

UniKey_Encrypt: UniKey_Encrypt is used when you want to encrypt an amount of memory with a key. The length of data must be a multiple of 8. This function only performs an encryption operation, and no compression functions are involved.

UniKey_Decrypt: For UniKey_Decrypt it is used when you want to decrypt an amount of memory with a key. The length of data must be a multiple of 8. Please use the key that was used to encrypt the data to decrypt it; otherwise it will not decrypt correctly. UniKey_Encrypt and UniKey_Decrypt offer a basic 128-bit encryption/decryption operation based on the UniKey’s hardware. You can call these functions when an encryption or decryption operation is needed. For better security, you can encrypt the credential before saving it into the UniKey’s memory.

UniKey_MD5: For UniKey_MD5 it is used when you want to make an MD5 digest for an amount of content or data.

The Advantages of Expert Level of Protection

There are twenty APIs for an expert level of protection:

long UniKey_Find(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_Find_Next(WORD* pHandle, DWORD* pSetting1, DWORD* pSetting2);

long UniKey_User_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2);

long UniKey_Vender_Logon(WORD* pHandle, WORD* pPassword1, WORD* pPassword2, WORD* pPassword3, WORD* pPassword4);

long UniKey_Write_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Read_Memory(WORD* pHandle, WORD* pStartAddress, WORD* pBufferLength, BYTE* pBuffer);

long UniKey_Write_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Read_SoftID(WORD* pHandle, DWORD* pSoftID);

long UniKey_Set_Module(WORD* pHandle, WORD* pModule, WORD* pValue, WORD* pDecrease);

long UniKey_Get_Module(WORD* pHandle, WORD* pModule, WORD* pValue);

long UniKey_Check_Module(WORD* pHandle, WORD* pModule, WORD* pValue, WORD* pDecrease);

long UniKey_Encrypt(WORD* pHandle, DWORD* pBufferLength, DWORD* pKeyNumber, BYTE *pBuffer);

long UniKey_Decrypt(WORD* pHandle, DWORD* pBufferLength, DWORD* pKeyNumber, BYTE *pBuffer);

long UniKey_MD5(WORD* pHandle, DWORD* pBufferLength, BYTE *pBuffer);

long UniKey_Seed(WORD* pHandle, DWORD* pSeed, WORD* pReturn1, WORD* pReturn2, WORD* pReturn3, WORD* pReturn4);

long UniKey_Write_Arithmetic(WORD* pHandle, WORD* pStartAddress, BYTE * pBuffer);

long UniKey_Calculate1(WORD* pHandle, DWORD* pStartAddress, DWORD* pModule, WORD* pRegA, WORD* pRegB, WORD* pRegC, WORD* pRegD);

long UniKey_Calculate2(WORD* pHandle, DWORD* pStartAddress, DWORD* pSeed, WORD* pRegA, WORD* pRegB, WORD* pRegC, WORD* pRegD);

long UniKey_Calculate3(WORD* pHandle, DWORD* pStartAddress, DWORD* pModule, WORD* pRegA, WORD* pRegB, WORD* pRegC, WORD* pRegD);

long UniKey_Logoff(WORD* pHandle);

The Advantage of Expert Protection

An expert level of protection incorporates arithmetic, however, at the cost of increased difficulty. You can enter several numbers for each register, then run the arithmetic which was written into memory. After that it will return a number for each register, these values are the result. Not only the one who uses your software needs to enter the correct number for each register, but they also should know the correct arithmetic. In this part you will learn how to apply an expert level of protection to your software. You can refer to the following picture and gain a quick understanding of it.

UniKey professional software protection level

The method enables you to have quick and easy protection for your software. All you need to do is to call several functions in your project. The main usage of the APIs is offered below.

UniKey_Seed: For UniKey_Seed it is used when you want to get return codes from the input of a seed code. This function's return values are related to *pSeed and UniKey dongle’s password. UniKey_Seed generates a set of seed codes. All of these seed codes are based on the password. It provides another method to verify the password and check the insertion of the dongle. Apart from this, the seed codes can be used in other computation. For example, you can use the seed returned as a 64-bit long encryption key.

UniKey_Write_Arithmetic: For UniKey_Write_Arithmetic it is used when you want to write user-defined mathematical algorithms. A successful operation will result in the user-defined algorithm populated with the algorithm command string from the buffer. UniKey_Write_Arithmetic is called when you write a series of algorithms into the dongle. This function is only called at the software-vendor side.

UniKey_Calculate1: For, UniKey_Calculate1, it is used when you want to return the results of a calculation performed in UniKey, using input provided by the developer and the Calculate1 function. When the calculation starts, the values of other internal registers are listed in the table below.

Internal Register Description
E High-order byte of reversed hardware ID
F Low-order byte of reversed hardware ID
G Value stored in license module *pModule
H Random number

UniKey_Calculate 2: For UniKey_Calculate2 it is used when you want to return the results of a calculation performed in UniKey, using input provided by the developer and the Calculate2 function. The initial values of register E, F, G and H are the return values of seed code *pSeed. To make it simple, UniKey calls function Seed with seed code *pSeed, and writes the return values to register E, F, G and H for the next operation.

UniKey_Calculate 3: For UniKey_Calculate 3, it is used when you want to return results of a calculation performed in UniKey, using input provided by the developer and the calculate3 function. The initial values of register E, F, G and H are the content of license module *lp2 and *lp2+1/2/3.