This is the 29th day of my participation in the August Wenwen Challenge.More challenges in August

An overview of the

The first two articles respectively introduced the use of time and limit the number of times used for encryption, in fact, there are many ways of encryption, today mainly introduced by obtaining the hardware information of the computer for encryption, but this method is not very good encryption effect, this should be divided into many kinds of situations. First, let’s look at the pros and cons

The advantages and disadvantages

Advantages:

  • After the user has used this software, it cannot be copied to other devices for use, only one machine can use

Disadvantages:

  • A newly packaged program that has not been run can be copied without control

If the program is connected to the Internet, it is easy to achieve an installation package for the number of installation statistics and other restrictions, the offline version of the no way. If anyone has a better way, please leave a comment. Another option is to know the MAC address or unique device identifier of the user’s computer in advance and write it directly into the program or save it locally for reading.

Thought analysis

As far as the author knows, Unity can get the MAC address and unique identifier of the computer. These two pieces of information are unlikely to be the same for every computer and can be used for encryption. First create a TXT in Unity under StreamAssets, write an encrypted data, the content can be customized, after the program starts, decrypt the data, see if it is the same as the specified data, the same shows that the program is run for the first time, obtain the local MAC address, and through the encryption algorithm to write local. If no, the data has been written and decrypted. If the data is the same as the local MAC address, continue. Otherwise, the program is unavailable. It is also possible to write the local MAC address or unique device identifier directly into the program, so that a fixed machine can be used (provided that the user’s computer information is obtained)

Function implementation

Data encryption

First let’s look at how the data is encrypted, and then we move on to the next step. Here we use RijndaelManaged encryption and decoding. You need to import the namespace using System. Security. Cryptography. The key must be the same when encrypting and decrypting data. Otherwise, different data parsing results or errors may occur. The main code is as follows

/// </summary> public static String Encrypt(string Text, string sKey) { byte[] keyArray = UTF8Encoding.UTF8.GetBytes(sKey); RijndaelManaged encryption = new RijndaelManaged(); encryption.Key = keyArray; encryption.Mode = CipherMode.ECB; encryption.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = encryption.CreateEncryptor(); byte[] _EncryptArray = UTF8Encoding.UTF8.GetBytes(Text); byte[] resultArray = cTransform.TransformFinalBlock(_EncryptArray, 0, _EncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); }Copy the code
/ / / < summary > / / / / / / decrypt data < / summary > / / / < param name = "Text" > to decrypt the contents of the < param > / / / < param name = "sKey" > key, must be 32 bits, </param> // <returns></returns> public static string Decrypt(string Text, string sKey) { try { byte[] keyArray = UTF8Encoding.UTF8.GetBytes(sKey); RijndaelManaged decipher = new RijndaelManaged(); decipher.Key = keyArray; decipher.Mode = CipherMode.ECB; decipher.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = decipher.CreateDecryptor(); byte[] _EncryptArray = Convert.FromBase64String(Text); byte[] resultArray = cTransform.TransformFinalBlock(_EncryptArray, 0, _EncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } catch {return "decryption error "; }}Copy the code

By calling the above two codes, we can test this out in Unity

// String to be encrypted string encrypt = string.empty; // Encrypted string string desEncrypt = string.empty; / / key, to encrypt and decrypt all need readonly string key = "45621488631456644633443346324661"; // Start is called before the first frame update void Start() {encrypt = "I am test data 123"; // Start is called before the first frame update void Start() {encrypt =" I am test data 123"; desEncrypt = DESEncrypt.Encrypt(encrypt, key); Debug.Log(encrypt + ">> result: >>" + desEncrypt); Debug.log (desEncrypt + ">> decryption results in >>" + desencrypt.decrypt (desEncrypt, key)); }Copy the code

The results

Obtaining a MAC Address

First of all, we need to quote System.Net.NetworkInformation assemblies in the script, and then use the NetworkInterface GetAllNetworkInterfaces () can get all the network related information, The GetPhysicalAddress() method obtains the Mac address of the device. Get all the information and then iterate to find the MAC address. The specific code is as follows:

/// <summary> // </summary> /// <returns></returns> private static String GetMacAddress() {string physicalAddress = ""; NetworkInterface[] allInfo = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adaper in allInfo) { if (adaper.Description == "en0") { physicalAddress = adaper.GetPhysicalAddress().ToString(); break; } else { physicalAddress = adaper.GetPhysicalAddress().ToString(); if (physicalAddress ! = "") { break; } } } return physicalAddress; }Copy the code

Running results:

Obtain the unique device ID

In Unity, there is a class SystemInfo, which is specially used to get information about the device. To obtain the unique identification of the device, a single sentence is required, as follows

SystemInfo.deviceUniqueIdentifier;
Copy the code

What he returns is a unique identifier for the device

And the result of that is

validation

First we create a TXT text into StreamingAssets, and then use the program to generate an encrypted initialization judgment statement, write in TXT.

Readonly string firstPlayStr = "This is the first time this program is run!" ; // Start is called before the first frame update void Start() Debug.Log(DESEncrypt.Encrypt(firstPlayStr, key)); }Copy the code

Copy printed information into text. (Copy manually, not procedurally, before packing) then read the text, decrypt it, and compare the data. The unique device identifier is used here. Read the text, first see whether there is a local file, read, do not directly exit the program

/// </summary> /// </returns> private String ReadTxt() {string STR = string.empty; If (file.exists (path)) {StreamReader sr = new StreamReader(path); str = sr.ReadToEnd(); sr.Close(); } else {/ / no data directly out of # if UNITY_EDITOR UnityEditor. EditorApplication. IsPlaying = false; #else Application.Quit(); #endif } return str; }Copy the code

And then read the decryption results of the data for comparison, the result is equal to the program for the first time, then obtain the unique identification of the device, and encryption, and then written into TXT, if the result is not the program for the first time, also with the unique identification of the device, exit the program

/ / read the data path = Application. StreamingAssetsPath + "/ info. TXT"; string readString = DESEncrypt.Decrypt(ReadTxt(), key); If (readString == firstPlayStr) {// Write unique identifier of encrypted data WriteTxt(new String [] { DESEncrypt.Encrypt(SystemInfo.deviceUniqueIdentifier, key) }); } else {/ / and the machine equipment identification contrast the if (SystemInfo. DeviceUniqueIdentifier. Equals (readString)) {/ / verification through} else {/ / # if UNITY_EDITOR authentication failure  UnityEditor.EditorApplication.isPlaying = false; #else Application.Quit(); #endif } }Copy the code

Write data

// </summary> // <param name="contents"></param> public void WriteTxt(string[] contents) {if (! File. The Exists (path)) {/ / File does not exist, exit the program # if UNITY_EDITOR UnityEditor. EditorApplication. IsPlaying = false; #else Application.Quit(); #endif } else { StreamWriter sw = new StreamWriter(path); foreach (var item in contents) { sw.WriteLine(item); } sw.Close(); }}Copy the code

Source code sharing

This is not the renderings, directly on the source code, a total of two, interested can download down to see GitHub download address: click here to jump to download

Write in the last

All the shared content is the author used in the daily development process of a variety of small function points, sharing is also a way to review, if there is a bad place to write, please give more advice. Welcome to learn from each other and make progress. This piece article is written here first, hope to be able to help you