在建立了个VC工程之后,需要建立主程序头文件KeyDll.h,加入如下代码。这些代码中定义了导出的四个函数。
class _declspec(dllexport) CkeyDllApp
{public:
BOOL GetChallenge();
int* Challenge();//导出函数
int* DecryptData(BYTE []);//导出函数,需要解密的随机数,可存储在数组InputNum[8]中。此函数输出值即为加密后的数据,输出格式为数组DESDeData[8]。
Int* EncryptData(BYTE []);//导出函数,需要加密的随机数,可存储在数组InputNum[8]中。此函数输出值即为加密后的数据,输出格式为数组DESEnData[8]
BOOL cha_gen;
void DESDecrypt ();//BYTE *Data,BYTE *Key); //解密函数定义
void DESEncrypt ();//BYTE *Bata,BYTE *Key); //加密函数定义
BOOL Init();
protected:
BYTE DESKey[8]; //密钥
BYTE IniDeData[8]; //外部输入的需要解密的数据
BYTE IniEnData[8]; //外部输入的加密前的随机数
BYTE DESDeData[8]; //解密后的数据
BYTE DESEnData[8]; //加密后的数据
WORD subkey[16][48]; //子密钥
BYTE challenge[8];
……}
然后,在主文件KeyDll.cpp中实现各功能函数的具体功能,主要是算法的实现。
BOOL CKeyDllApp::GetChallenge()//这是产生随机数的函数,它调用API的函数srand(),最终产生的8位随机数存在数组challenge[8]中
{
int i;
srand((unsigned)time (NULL));
if(!cha_gen){
for(i=0;i<8;i++){
do{challenge[i]=(rand()/256);}
while((challenge[i]=='')||(challenge[i] = =0)||(challenge[i]==255)||(challenge[i]==256-''));}
challenge[8]=0;
cha_gen=TRUE;
return TRUE;}
retur FALSE;}
void CKeyDllApp::DESDecrypt ()//解密函数,完成对已加密的8位随机数的解密功能
{
WORD TempInput[64],TempOutput[64],TempKey[64];
Stringtobit (IniDeData,TempInput);
Stringtobit (DESKey,TempKey);
decry (TempInput,TempKey,TempOutput);
bittostring (TempOutput,DESDeData);}
void CKeyDllApp::DESEncrypt() //加密函数,可完成对8位随机数的加密功能,然后可与原随机数比较,看是否相等
{
WORD TempInput [64],TempOutput[64],TempKey[64];
stringtobit (IniEnData,TempInput);
stringtobit (DESKey,TempKey);
encry(TempInput,TempKey,TempOutput);
bittostring (TempOutput,DESEnData);}
int* CKeyDllApp::DecryptData (BYTE InputDeNum[8])//导出获取解密数据的函数。此函数需要赋值??已加密了的8位随机数,并进行解密,最终函数值为解密后的8位随机数
{
int i;
for (i=0;I<8;i++)
IniDeData[i]=InputDeNum[8];
return (int *)DESDeData;}
int* CKeyDllapp::EncryptData (BYTE InputEnNum [8])//导出的获取加密数据的函数。此函数需要赋值??8位随机数,直接调用并赋8位随机数后,此函数将调用加密函数并进行加密,最终函数值为加密后的8位随机数
{
int I;
for (i=0;i<8;i++)
IniEnData[i]=InputEnNum[i];
Return (int *)DESEnData;}
编译、连接后接产生一系列文件,在加上源工程文件,将会有数量比较庞大的文件系统。最终,只需提供给用户三个文件即可,它们是:
?.dll,这是DLL文件;
?.lib,这个文件将在应用DLL的程序编程和连接时,提供连接向导;
?.h,这个头文件告诉用户此DLL中导出了哪些量可以用。
DES的DLL导出了一个类:CkeyDllApp。在这个类中共有4个导出函数可以导入应用程序中,用户在导入了加密DLL后,可以在自己的程序中直接调用以下函数:
?BOOL GetChallenge(),用于在应用程序支持循环结构;
?int *Challenge(),产生随机数,并存储在Challenge[8]中;
?int *DecryptData(BYTE []),用于解密随机数;
?int *EncryptData(BYTE []),用于加密随机数。
2.2 USB安全钥新增功能描述
USB安全钥和PC传输的数据量不大,而且没有很高的速度要求。因此,在编写固件时就将其归类为HID(USB的人机接口设备类)。在编写PC端的驱动程序时可以直接调用Windows提供的HID的API函数,大大降低了编程的难度。更重要的是,Windows对HID设备的支持非常完备,不需要用户再编写底层的驱动。
安全钥端的设计内容主要是:实现在线修改存储在安全钥内的KeyID和读取KeyID两个功能,分别由函数Set_KeyID和Get_KeyID实现。KeyID是安全钥的标识符,在安全钥插到PC上后,被读出并送往Server进行检查。在初期产品中,KeyID只能是安全钥首次接到PC上读取,且不能更改,这为厂家和开发者造成了不便。因此要更改初期产品中的KeyID,这必须修改安全钥端的汇编程序,然后再“烧”写到安全钥中,非常麻烦。新增功能可实现KeyID的在线修改。
PC端的设计包括两步。首先要实现在PC上读取安全钥内的KeyID。通过安全钥的端点1,8个字节的KeyID被周期地送出。PC要获取这些数据,调用HID类库Get_Report(Feature)。从安全钥发来的包含KeyID的包的特性及技术指标如表1。
表1 调用HID类库获取KeyID
| bmRequestType | bRequest | wValueL | wValueH | wIndex | wLength | Data |
| 10100001B($A1) | Get_Report($01) | Zero | Feature($03) | Zero | 8 | KeyID |

