一、硬件狗加密的效果,实现以下效果:
1、在软件运行时,先检测硬件狗是否存在,如不存在,则报错,无法进入软件。
2、在软件运行过程中,如果检测到硬件狗拔出,则软件所有的功能变为不可用(灰色)
二、实现方法
1、在硬件狗厂商的软件中,生成加密代码。
2、在入口处,增加硬件狗是否存在的判断。如不存在,则程序退出
//验证硬件狗是否存在
if (! CheckYingJianGou.CheckGou())//如果没找到加密锁,则返回
{
return;
}
以下是验证硬件狗是否存在的类
public class CheckYingJianGou
{
/// <summary>
/// 检查硬件狗是否存在,如果存在返回true,如果不存在,返回FALSE,放在入口函数进行判断
/// </summary>
/// <returns></returns>
public static bool CheckGou()
{
bool a = true;//假设硬件狗存在
初始化我们的操作加密锁的类
SoftKey ytsoftkey = new SoftKey();
//使用普通算法一来检查是否存在指定的加密锁
if (ytsoftkey.CheckKeyByFindort_2() != 0)
{
XtraMessageBox.Show("未能找到加密锁或加密锁不匹配!", "警告");
return false;
}
//使用增强算法一来检查是否存在指定的加密锁
int ret;
ret = ytsoftkey.CheckKeyByEncstring();
if (ret != 0)
{
XtraMessageBox.Show("未能找到加密锁或加密锁不匹配!", "警告");
return false;
}
//使用读写储存器来检查是否存在指定的加密锁
int ret2;
ret2 = ytsoftkey.CheckKeyByReadEprom();
if (ret2 != 0)
{
XtraMessageBox.Show("未能找到加密锁或加密锁不匹配!", "警告");
return false;
}
//使用增强算法二来检查是否存在指定的加密锁
int ret3;
ret3 = ytsoftkey.CheckKeyByEncstring_New();
if (ret3 != 0)
{
XtraMessageBox.Show("未能找到加密锁或加密锁不匹配!", "警告");
return false;
}
return a;
}
}
以下是加密狗厂商生成的类文件
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
//公共函数说明
//***查找加密锁
//int FindPort(int start, ref string OutKeyPath);
//查找指定的加密锁(使用普通算法一)
//int FindPort_2(int start, int in_data, int verf_data, ref string OutKeyPath);
//***获到锁的版本
//int NT_GetIDVersion(ref short version, string KeyPath);
//获到锁的扩展版本
//int NT_GetIDVersionEx(ref short version, string KeyPath);
//***获到锁的ID
//int GetID(ref int id_1, ref int id_2, string KeyPath);
//***从加密锁中读取一批字节
//int YReadEx(byte[] OutData, short Address, short mylen, string HKey, string LKey, string KeyPath);
//***从加密锁中读取一个字节数据,一般不使用
//int YRead(ref byte OutData, short Address,string HKey, string LKey, string KeyPath);
//***写一批字节到加密锁中
//int YWriteEx(byte[] InData, short Address, short mylen, string HKey, string LKey, string KeyPath);
//***写一个字节的数据到加密锁中,一般不使用
//int YWrite(byte InData, short Address, string HKey, string LKey, string KeyPath);
//***从加密锁中读字符串
//int YReadString(ref string outstring, short Address, short mylen, string HKey, string LKey, string KeyPath);
//***写字符串到加密锁中
//int YWriteString(string InString, short Address, string HKey, string LKey, string KeyPath);
//***算法函数
//int sWriteEx(int in_data , ref int out_data , string KeyPath);
//int sWrite_2Ex(int in_data , ref int out_data ,string KeyPath);
//int sRead(ref int in_data, string KeyPath);
//int sWrite(int out_data, string KeyPath);
//int sWrite_2(int out_data, string KeyPath);
//***设置写密码
//int SetWritePassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string KeyPath);
//***设置读密码
//int SetReadPassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string KeyPath);
//'设置增强算法密钥一
//int SetCal_2(string Key , string KeyPath);
//使用增强算法一对字符串进行加密
//int EncString(string InString , ref string outstring , string KeyPath);
//使用增强算法一对二进制数据进行加密
// int Cal(byte[] InBuf, byte[] OutBuf, string KeyPath);
//'设置增强算法密钥二
//int SetCal_New(string Key , string KeyPath);
//使用增强算法二对字符串进行加密
//int EncString_New(string InString , ref string outstring , string KeyPath);
//使用增强算法二对二进制数据进行加密
// int Cal_New(byte[] InBuf, byte[] OutBuf, string KeyPath);
//***初始化加密锁函数
//int ReSet( string Path);
//***获取字符串长度
//int lstrlenA(string InString );
namespace WindowsApplication1
{
public struct GUID
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte [] Data1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] Data2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] Data3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data4;
}
public struct SP_INTERFACE_DEVICE_DATA
{
public int cbSize;
public GUID InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}
public struct SP_DEVINFO_DATA
{
public int cbSize;
public GUID ClassGuid;
public int DevInst;
public IntPtr Reserved;
}
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public byte[] DevicePath;
}
public struct HIDD_ATTRIBUTES
{
public int Size;
public ushort VendorID;
public ushort ProductID;
public ushort VersionNumber;
}
public struct HIDP_CAPS
{
public short Usage;
public short UsagePage;
public short InputReportByteLength;
public short OutputReportByteLength;
public short FeatureReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public short[] Reserved;
public short NumberLinkCollectionNodes;
public short NumberInputButtonCaps;
public short NumberInputValueCaps;
public short NumberInputDataIndices;
public short NumberOutputButtonCaps;
public short NumberOutputValueCaps;
public short NumberOutputDataIndices;
public short NumberFeatureButtonCaps;
public short NumberFeatureValueCaps;
public short NumberFeatureDataIndices;
}
class SoftKey
{
private const ushort VID = 0x3689;
private const ushort PID = 0x8762;
private const ushort PID_NEW= 0X2020;
private const ushort VID_NEW = 0X3689;
private const ushort PID_NEW_2 = 0X2020;
private const ushort VID_NEW_2 = 0X2020;
private const short DIGCF_PRESENT = 0x2;
private const short DIGCF_DEVICEINTERFACE = 0x10;
private const short INVALID_HANDLE_VALUE = (-1);
private const short ERROR_NO_MORE_ITEMS = 259;
private const uint GENERIC_READ = 0x80000000;
private const int GENERIC_WRITE = 0x40000000;
private const uint FILE_SHARE_READ = 0x1;
private const uint FILE_SHARE_WRITE = 0x2;
private const uint OPEN_EXISTING = 3;
private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
private const uint INFINITE = 0xFFFF;
private const short MAX_LEN = 495;
public const int FAILEDGENKEYPAIR = -21;
public const int FAILENC = -22;
public const int FAILDEC = -23;
public const int FAILPINPWD = -24;
public const int USBStatusFail = -50; //USB操作失败,可能是没有找到相关的指令
public const int SM2_ADDBYTE = 97;//加密后的数据会增加的长度
public const int MAX_ENCLEN = 128; //最大的加密长度分组
public const int MAX_DECLEN = (MAX_ENCLEN + SM2_ADDBYTE); //最大的解密长度分组
public const int SM2_USENAME_LEN = 80;// '最大的用户名长度
public const int ECC_MAXLEN = 32;
public const int PIN_LEN = 16;
private const byte GETVERSION = 0x01;
private const byte GETID = 0x02;
private const byte GETVEREX = 0x05;
private const byte CAL_TEA = 0x08;
private const byte SET_TEAKEY = 0x09;
private const byte READBYTE = 0x10;
private const byte WRITEBYTE = 0x11;
private const byte YTREADBUF = 0x12;
private const byte YTWRITEBUF = 0x13;
private const byte MYRESET = 0x20;
private const byte YTREBOOT = 0x24;
private const byte SET_ECC_PARA = 0x30;
private const byte GET_ECC_PARA = 0x31;
private const byte SET_ECC_KEY = 0x32;
private const byte GET_ECC_KEY = 0x33;
private const byte MYENC = 0x34;
private const byte MYDEC = 0X35;
private const byte SET_PIN = 0X36;
private const byte GEN_KEYPAIR = 0x37;
private const byte YTSIGN = 0x51;
private const byte YTVERIFY = 0x52;
private const byte GET_CHIPID = 0x53;
private const byte YTSIGN_2 = 0x53;
[DllImport("kernel32.dll")]
public static extern int lstrlenA(string InString);
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
public static extern void CopyStringToByte(byte[] pDest, string pSourceg, int ByteLenr);
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
public static extern void CopyByteToString(StringBuilder pDest, byte[] pSource, int ByteLenr);
[DllImport("HID.dll")]
private static extern bool HidD_GetAttributes(IntPtr HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
[DllImport("HID.dll")]
private static extern int HidD_GetHidGuid(ref GUID HidGuid);
[DllImport("HID.dll")]
private static extern bool HidD_GetPreparsedData(IntPtr HidDeviceObject, ref IntPtr PreparsedData);
[DllImport("HID.dll")]
private static extern int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities);
[DllImport("HID.dll")]
private static extern bool HidD_FreePreparsedData(IntPtr PreparsedData);
[DllImport("HID.dll")]
private static extern bool HidD_SetFeature(IntPtr HidDeviceObject, byte[] ReportBuffer, int ReportBufferLength);
[DllImport("HID.dll")]
private static extern bool HidD_GetFeature(IntPtr HidDeviceObject, byte[] ReportBuffer, int ReportBufferLength);
[DllImport("SetupApi.dll")]
private static extern IntPtr SetupDiGetClassDevsA(ref GUID ClassGuid, int Enumerator, int hwndParent, int Flags);
[DllImport("SetupApi.dll")]
private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("SetupApi.dll")]
private static extern bool SetupDiGetDeviceInterfaceDetailA(IntPtr DeviceInfoSet, ref SP_INTERFACE_DEVICE_DATA DeviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int RequiredSize, IntPtr DeviceInfoData);
[DllImport("SetupApi.dll")]
private static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref GUID InterfaceClassGuid, int MemberIndex, ref SP_INTERFACE_DEVICE_DATA DeviceInterfaceData);
[DllImport("kernel32.dll", EntryPoint = "CreateFileA")]
private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, uint hTemplateFile);
[DllImport("kernel32.dll")]
private static extern int CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
private static extern int GetLastError();
[DllImport("kernel32.dll", EntryPoint = "CreateSemaphoreA")]
private static extern IntPtr CreateSemaphore(int lpSemaphoreAttributes, int lInitialCount, int lMaximumCount, string lpName);
[DllImport("kernel32.dll")]
private static extern int WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
[DllImport("kernel32.dll")]
private static extern int ReleaseSemaphore(IntPtr hSemaphore, int lReleaseCount, int lpPreviousCount);
//以下函数用于将字节数组转化为宽字符串
private static string ByteConvertString(byte[] buffer)
{
char[] null_string ={ '\0', '\0' };
System.Text.Encoding encoding = System.Text.Encoding.Default;
return encoding.GetString(buffer).TrimEnd(null_string);
}
//以下用于将16进制字符串转化为无符号长整型
private uint HexToInt(string s)
{
string[] hexch = { "0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "A", "B", "C", "D", "E", "F"};
s = s.ToUpper();
int i, j;
int r, n, k;
string ch;
k = 1; r = 0;
for (i = s.Length; i > 0; i--)
{
ch = s.Substring(i - 1, 1);
n = 0;
for (j = 0; j < 16; j++)
if (ch == hexch[j])
n = j;
r += (n * k);
k *= 16;
}
return unchecked((uint)r);
}
private int HexStringToByteArray(string InString, ref byte [] b)
{
int nlen;
int retutn_len;
int n,i;
string temp;
nlen = InString.Length;
if (nlen < 16) retutn_len = 16;
retutn_len = nlen / 2;
b = new byte[retutn_len];
i = 0;
for(n=0;n<nlen;n=n+2)
{
temp = InString.Substring( n, 2);
b[i] =(byte) HexToInt(temp);
i = i + 1;
}
return retutn_len;
}
public void EnCode(byte[] inb, byte[] outb, string Key)
{
UInt32 cnDelta, y, z, a, b, c, d, temp_2;
UInt32[] buf = new UInt32[16];
int n, i, nlen;
UInt32 sum;
//UInt32 temp, temp_1;
string temp_string;
cnDelta = 2654435769;
sum = 0;
nlen = Key.Length;
i = 0;
for (n = 1; n <= nlen; n = n + 2)
{
temp_string = Key.Substring(n - 1, 2);
buf[i] = HexToInt(temp_string);
i = i + 1;
}
a = 0; b = 0; c = 0; d = 0;
for (n = 0; n <= 3; n++)
{
a = (buf[n] << (n * 8)) | a;
b = (buf[n + 4] << (n * 8)) | b;
c = (buf[n + 4 + 4] << (n * 8)) | c;
d = (buf[n + 4 + 4 + 4] << (n * 8)) | d;
}
y = 0;
z = 0;
for (n = 0; n <= 3; n++)
{
temp_2 = inb[n];
y = (temp_2 << (n * 8)) | y;
temp_2 = inb[n + 4];
z = (temp_2 << (n * 8)) | z;
}
n = 32;
while (n > 0)
{
sum = cnDelta + sum;
/*temp = (z << 4) & 0xFFFFFFFF;
temp = (temp + a) & 0xFFFFFFFF;
temp_1 = (z + sum) & 0xFFFFFFFF;
temp = (temp ^ temp_1) & 0xFFFFFFFF;
temp_1 = (z >> 5) & 0xFFFFFFFF;
temp_1 = (temp_1 + b) & 0xFFFFFFFF;
temp = (temp ^ temp_1) & 0xFFFFFFFF;
temp = (temp + y) & 0xFFFFFFFF;
y = temp & 0xFFFFFFFF;*/
y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
/*temp = (y << 4) & 0xFFFFFFFF;
temp = (temp + c) & 0xFFFFFFFF;
temp_1 = (y + sum) & 0xFFFFFFFF;
temp = (temp ^ temp_1) & 0xFFFFFFFF;
temp_1 = (y >> 5) & 0xFFFFFFFF;
temp_1 = (temp_1 + d) & 0xFFFFFFFF;
temp = (temp ^ temp_1) & 0xFFFFFFFF;
temp = (z + temp) & 0xFFFFFFFF;
z = temp & 0xFFFFFFFF;*/
z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
n = n - 1;
}
for (n = 0; n <= 3; n++)
{
outb[n] = System.Convert.ToByte((y >> (n * 8)) & 255);
outb[n + 4] = System.Convert.ToByte((z >> (n * 8)) & 255);
}
}
public void DeCode(byte[] inb, byte[] outb, string Key)
{
UInt32 cnDelta, y, z, a, b, c, d, temp_2;
UInt32[] buf = new UInt32[16];
int n, i, nlen;
UInt32 sum;
//UInt32 temp, temp_1;
string temp_string;
cnDelta = 2654435769;
sum = 0xC6EF3720;
nlen = Key.Length;
i = 0;
for (n = 1; n <= nlen; n = n + 2)
{
temp_string = Key.Substring(n - 1, 2);
buf[i] = HexToInt(temp_string);
i = i + 1;
}
a = 0; b = 0; c = 0; d = 0;
for (n = 0; n <= 3; n++)
{
a = (buf[n] << (n * 8)) | a;
b = (buf[n + 4] << (n * 8)) | b;
c = (buf[n + 4 + 4] << (n * 8)) | c;
d = (buf[n + 4 + 4 + 4] << (n * 8)) | d;
}
y = 0;
z = 0;
for (n = 0; n <= 3; n++)
{
temp_2 = inb[n];
y = (temp_2 << (n * 8)) | y;
temp_2 = inb[n + 4];
z = (temp_2 << (n * 8)) | z;
}
n = 32;
while (n-- > 0)
{
z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
sum -= cnDelta;
}
for (n = 0; n <= 3; n++)
{
outb[n] = System.Convert.ToByte((y >> (n * 8)) & 255);
outb[n + 4] = System.Convert.ToByte((z >> (n * 8)) & 255);
}
}
public string StrEnc(string InString, string Key)//使用增强算法,加密字符串
{
byte[] b, outb;
byte[] temp = new byte[8], outtemp = new byte[8];
int n, i, nlen, outlen;
string outstring;
nlen = lstrlenA(InString) + 1;
if (nlen < 8)
outlen = 8;
else
outlen = nlen;
b = new byte[outlen];
outb = new byte[outlen];
CopyStringToByte(b, InString, nlen);
b.CopyTo(outb, 0);
for (n = 0; n <= outlen - 8; n = n + 8)
{
for (i = 0; i < 8; i++) temp[i] = b[i + n];
EnCode(temp, outtemp, Key);
for (i = 0; i < 8; i++) outb[i + n] = outtemp[i];
}
outstring = "";
for (n = 0; n <= outlen - 1; n++)
{
outstring = outstring + outb[n].ToString("X2");
}
return outstring;
}
public string StrDec(string InString, string Key) //使用增强算法,加密字符串
{
byte[] b, outb;
byte[] temp = new byte[8], outtemp = new byte[8];
int n, i, nlen, outlen;
string temp_string;
StringBuilder c_str;
nlen = InString.Length;
if (nlen < 16) outlen = 16;
outlen = nlen / 2;
b = new byte[outlen];
outb = new byte[outlen];
i = 0;
for (n = 1; n <= nlen; n = n + 2)
{
temp_string = InString.Substring(n - 1, 2);
b[i] = System.Convert.ToByte(HexToInt(temp_string));
i = i + 1;
}
b.CopyTo(outb, 0);
for (n = 0; n <= outlen - 8; n = n + 8)
{
for (i = 0; i < 8; i++) temp[i] = b[i + n];
DeCode(temp, outtemp, Key);
for (i = 0; i < 8; i++) outb[i + n] = outtemp[i];
}
c_str = new StringBuilder("", outlen);
CopyByteToString(c_str, outb, outlen);
return c_str.ToString();
}
private bool isfindmydevice(int pos, ref int count, ref string OutPath)
{
return Subisfindmydevice(pos,ref count,ref OutPath);
}
private bool Subisfindmydevice(int pos, ref int count, ref string OutPath)
{
IntPtr hardwareDeviceInfo;
SP_INTERFACE_DEVICE_DATA DeviceInfoData= new SP_INTERFACE_DEVICE_DATA();
int i;
GUID HidGuid=new GUID();
SP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData= new SP_DEVICE_INTERFACE_DETAIL_DATA();
int requiredLength;
IntPtr d_handle;
HIDD_ATTRIBUTES Attributes= new HIDD_ATTRIBUTES();
i = 0; count = 0;
HidD_GetHidGuid(ref HidGuid);
hardwareDeviceInfo = SetupDiGetClassDevsA(ref HidGuid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hardwareDeviceInfo == (IntPtr)INVALID_HANDLE_VALUE)return false;
DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData);
while (SetupDiEnumDeviceInterfaces(hardwareDeviceInfo, IntPtr.Zero, ref HidGuid, i, ref DeviceInfoData))
{
if (GetLastError() == ERROR_NO_MORE_ITEMS )break;
if (System.IntPtr.Size == 4)
functionClassDeviceData.cbSize = 5;
else
functionClassDeviceData.cbSize = 8;
requiredLength = 0;
if (!SetupDiGetDeviceInterfaceDetailA(hardwareDeviceInfo, ref DeviceInfoData, ref functionClassDeviceData, 300, ref requiredLength, IntPtr.Zero) )
{
SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
return false;
}
OutPath = ByteConvertString(functionClassDeviceData.DevicePath);
d_handle = CreateFile(OutPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if ((IntPtr)INVALID_HANDLE_VALUE != d_handle )
{
if (HidD_GetAttributes(d_handle, ref Attributes))
{
if ((Attributes.ProductID == PID) && (Attributes.VendorID == VID) ||
(Attributes.ProductID == PID_NEW) && (Attributes.VendorID == VID_NEW) ||
(Attributes.ProductID == PID_NEW_2) && (Attributes.VendorID == VID_NEW_2))
{
if (pos == count)
{
SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
CloseHandle(d_handle);
return true;
}
count = count + 1;
}
}
CloseHandle(d_handle);
}
i = i + 1;
}
SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
return false;
}
private bool GetFeature(IntPtr hDevice, byte[] array_out, int out_len)
{
bool FeatureStatus;
bool Status;
int i;
byte []FeatureReportBuffer=new byte[512];
IntPtr Ppd =System.IntPtr.Ze