천객만래 [千客萬來] (It has an interminable succession of visitors)
[mfc] WINDOWS API를 이용한 암호화 간단 예제

#include "stdafx.h"
#include <Windows.h>
#include <WinCrypt.h>

#define    MY_PASS       "papaya"           // 패스워드
#define    KeyLen        0x0080 * 0x10000    // 128-bit

int _tmain(int argc, _TCHAR* argv[])
{

    HCRYPTPROV    hProv;
    HCRYPTHASH    hHash;
    HCRYPTKEY     hKey;

    BYTE          pbData[100] = "TEST TEST TEST REAL TEST";
    DWORD         dwDataLen = (DWORD)strlen((char*)pbData) + 1;

    // CSP(Crystographic Service Provider) 핸들 얻기

    if(!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, 
                            PROV_RSA_FULL, 0))
    {
        // 유저용 키 컨테이너 만들기
        if(!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV,
                                PROV_RSA_FULL, CRYPT_NEWKEYSET))
        {
            printf("유저용 키 켄테이너 만들기 에러\n");
            return 1;
        }
    }

    // 해쉬 만들기
    if(!CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash))
    {
        printf("해쉬 만들기 에러\n");
        return 2;
    }

    // 해쉬 값 계산
    if(!CryptHashData(hHash, (BYTE*)MY_PASS, (DWORD)strlen(MY_PASS), 0))
    {
        printf("해쉬 값 계산 에러\n");
        return 3;
    }

    // 키 만들기
    if(!CryptDeriveKey(hProv, CALG_RC4, hHash, KeyLen, &hKey))
    {
        printf("키 만들기 에러\n");
        return 4;
    }

    // 암호화
    if(!CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 100))
    {
        printf("암호화 에러\n");
        return 5;
    }
    printf("암호건 문자 -> %s\n", pbData);

    // 복호화
    if(!CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen))
    {
        printf("복호화 에러\n");
        return 6;
    }
    printf("암호푼 문자 -> %s\n", pbData);

    // 해쉬 없애기
    CryptDestroyHash(hHash);

    // CSP 핸들 풀어주기
    CryptReleaseContext(hProv, 0);

    return 0;
}


Posted by SB패밀리

[C#] 라이선스용 컴퓨터 유일키 생성

Introduction

For licensing purpose according to me the best way and secure way is to generate an unique key for client's machine and providing a corresponding license key for that key. For this purpose you can take help of the unique id of client's computer's motherboard, BIOS and processor's. When you get these IDs you can generate any key of your preferable format.

Year ago I found a very handy and useful code in C# by searching net to get these IDs. And its serving me perfectly so far. Thanks to the original author of the code.

I added some additional code to generate a 128 bit key of a machine. The output is a nice looking key in hexadecimal format (eg. 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9)

Suggestions

I have few suggestions on this regard.

*) Generate key from only Motherboard, Processor and BIOS. Since user normally doesn't chagne these parts.

*) Don't use MAC ID, Graphics Card ID AND Disk ID. Since its very common to change these devices.

*) It takes significant time to get IDs of devices. So make the finger print generating fucntion static and save it in a static variable so that it generates the key only for one time in the whole application.

The Code

Here is the class. The code in the region "Original Device ID Getting Code" is from the original author.

 ==============================================================================

using System;
using System.Management;
using System.Security.Cryptography;
using System.Security;
using System.Collections;
using System.Text;
namespace Security
{
    /// <summary>
    /// Generates a 16 byte Unique Identification code of a computer
    /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
    /// </summary>
    public class FingerPrint 
    {
        private static string fingerPrint = string.Empty;
        public static string Value()
        {
            if (string.IsNullOrEmpty(fingerPrint))
            {
                fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId()
                            //+"\nDISK >> "+ diskId() + "\nVIDEO >> " + videoId() +"\nMAC >> "+ macId()
                                     );
            }
            return fingerPrint;
        }
        private static string GetHash(string s)
        {
            MD5 sec = new MD5CryptoServiceProvider();
            ASCIIEncoding enc = new ASCIIEncoding();
            byte[] bt = enc.GetBytes(s);
            return GetHexString(sec.ComputeHash(bt));
        }
        private static string GetHexString(byte[] bt)
        {
            string s = string.Empty;
            for (int i = 0; i < bt.Length; i++)
            {
                byte b = bt[i];
                int n, n1, n2;
                n = (int)b;
                n1 = n & 15;
                n2 = (n >> 4) & 15;
                if (n2 > 9)
                    s += ((char)(n2 - 10 + (int)'A')).ToString();
                else
                    s += n2.ToString();
                if (n1 > 9)
                    s += ((char)(n1 - 10 + (int)'A')).ToString();
                else
                    s += n1.ToString();
                if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
            }
            return s;
        }
        #region Original Device ID Getting Code
        //Return a hardware identifier
        private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
        {
            string result = "";
            System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
            System.Management.ManagementObjectCollection moc = mc.GetInstances();
            foreach (System.Management.ManagementObject mo in moc)
            {
                if (mo[wmiMustBeTrue].ToString() == "True")
                {
                    //Only get the first one
                    if (result == "")
                    {
                        try
                        {
                            result = mo[wmiProperty].ToString();
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
            }
            return result;
        }
        //Return a hardware identifier
        private static string identifier(string wmiClass, string wmiProperty)
        {
            string result = "";
            System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
            System.Management.ManagementObjectCollection moc = mc.GetInstances();
            foreach (System.Management.ManagementObject mo in moc)
            {
                //Only get the first one
                if (result == "")
                {
                    try
                    {
                        result = mo[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                    }
                }
            }
            return result;
        }
        private static string cpuId()
        {
            //Uses first CPU identifier available in order of preference
            //Don't get all identifiers, as very time consuming
            string retVal = identifier("Win32_Processor", "UniqueId");
            if (retVal == "") //If no UniqueID, use ProcessorID
            {
                retVal = identifier("Win32_Processor", "ProcessorId");
                if (retVal == "") //If no ProcessorId, use Name
                {
                    retVal = identifier("Win32_Processor", "Name");
                    if (retVal == "") //If no Name, use Manufacturer
                    {
                        retVal = identifier("Win32_Processor", "Manufacturer");
                    }
                    //Add clock speed for extra security
                    retVal += identifier("Win32_Processor", "MaxClockSpeed");
                }
            }
            return retVal;
        }
        //BIOS Identifier
        private static string biosId()
        {
            return identifier("Win32_BIOS", "Manufacturer")
            + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
            + identifier("Win32_BIOS", "IdentificationCode")
            + identifier("Win32_BIOS", "SerialNumber")
            + identifier("Win32_BIOS", "ReleaseDate")
            + identifier("Win32_BIOS", "Version");
        }
        //Main physical hard drive ID
        private static string diskId()
        {
            return identifier("Win32_DiskDrive", "Model")
            + identifier("Win32_DiskDrive", "Manufacturer")
            + identifier("Win32_DiskDrive", "Signature")
            + identifier("Win32_DiskDrive", "TotalHeads");
        }
        //Motherboard ID
        private static string baseId()
        {
            return identifier("Win32_BaseBoard", "Model")
            + identifier("Win32_BaseBoard", "Manufacturer")
            + identifier("Win32_BaseBoard", "Name")
            + identifier("Win32_BaseBoard", "SerialNumber");
        }
        //Primary video controller ID
        private static string videoId()
        {
            return identifier("Win32_VideoController", "DriverVersion")
            + identifier("Win32_VideoController", "Name");
        }
        //First enabled network card ID
        private static string macId()
        {
            return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
        }
        #endregion
    }
}

Posted by SB패밀리