一。c51的开发环境的搭建
    我用的Keil uVision2 6.12,在%\EliteIV_V2.3.2\ide\keil目录下有个Wizard.exe,安装之后基本就把keil的环境搭好了。没什么好说的。
    但是在编译代码的时候,提示找不到制定的.lib文件。。。于是就把ses_v3.h ,Ses51L.LIB文件在我的工程目录里也放了一份,并且加入到工程中。编译通过。

二。C51代码
    利用SenseLock提供的hash方法,实现的一个hash方法,供pc端调用

#include <ses_v3.h>
#include "string.h"

void main()
{
    /*varible*/
    BYTE digest[20];
    BYTE ret = 0;
    HASH_CONTEXT hctx;
   
    /*read buffer*/
    BYTE *p = pbInBuff;
    int len = bInLen;

    /*init hash*/
    ret = _sha1_init(&hctx);
    if (ret != SES_SUCCESS)
    {
 _set_response(1, &ret);
 _exit();
    }

    /*write hash*/
    ret = _sha1_update(&hctx, p, len);
    if (ret != SES_SUCCESS)
    {
 _set_response(1, &ret);
 _exit();
    }

    /*final hash*/
    ret = _sha1_final(&hctx, digest);
    if (ret != SES_SUCCESS)
    {
 _set_response(1, &ret);
 _exit();
    }

    _set_response(20,digest);
    _exit();
}


pc端环境搭建
1.新建一个win32 dll项目。把sense4.h,sense4.lib放到项目目录下面一份。并且添加到项目中。(vc6中有个项目设置,能指定.h,.lib文件的目录。vs2005不知道把这个选项改到什么地方去了,算了,不找了,直接copy一份算了。

2.添加一个.def文件
LIBRARY "SenseLockVC"
DESCRIPTION     'BeQuick'
EXPORTS
SenseLock_Hash     @1

3.pc端vc代码
// SenseLockVC.cpp : 定义 DLL 应用程序的入口点。
//SenseLock调用dll,包装SenseLock的调用函数,供C#调用

#include "stdafx.h"
#include <stdlib.h>
#include <conio.h>
#include "sense4.h"

#ifdef _MANAGED
#pragma managed(push, off)
#endif

//dll的入口函数
BOOL APIENTRY DllMain( HMODULE hModule,
  DWORD  ul_reason_for_call,
  LPVOID lpReserved
      )
{
 switch(ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
  break;
 case DLL_THREAD_ATTACH:
  break;
 case DLL_THREAD_DETACH:
  break;
 case DLL_PROCESS_DETACH:
  break;
 }
    return TRUE;
}
/*************************************************************************
*功能:调用SenseLock设备的函数
*输入参数:
*char *fid : 要调用的SenseLock程序文件名
*BYTE* inbuffer:    指向输入数据内存单元的指针
*DWORD inlen:输入数据内存单元长度
*BYTE* outbuffer:   指向输出数据内存单元的指针
*DWORD outlen:      输出数据内存单元长度
*DWORD* outSize:    输出数据的实际使用长度
*输出值:
*int :返回0为调用成功,返回非0为调用失败
**************************************************************************/
int call_sense4(char *fid, BYTE* inbuffer, DWORD inlen,BYTE* outbuffer,DWORD outlen,DWORD* outSize)
{
 /* See remarks for details.*/
 SENSE4_CONTEXT ctx = {0};

 SENSE4_CONTEXT *pctx = NULL;
 DWORD size = 0;
 DWORD ret = 0;

    /*枚举设备*/
 S4Enum(pctx, &size);
 if (size == 0)
 {
  return 1;
 }

 /*申请内存*/
 pctx = (SENSE4_CONTEXT *)malloc(size);
 if (pctx == NULL)
 {
  return 2;
 }
 ret = S4Enum(pctx, &size);
 if (ret != S4_SUCCESS)
 {
  free(pctx);
     return 3;
 }
 memcpy(&ctx, pctx, sizeof(SENSE4_CONTEXT));
 free(pctx);
 pctx = NULL;

 /*打开设备*/
 ret = S4Open(&ctx);
 if (ret != S4_SUCCESS)
 {
  return 4;
 }

 /*访问目录*/
 ret = S4ChangeDir(&ctx, "\\");
 if (ret != S4_SUCCESS)
 {
  S4Close(&ctx);
  return 5;
 }
 /*password
 验证密码*/
 BYTE b[] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};
 ret = S4VerifyPin(&ctx, b, 8, S4_USER_PIN);
 if (ret != S4_SUCCESS)
 {
  S4Close(&ctx);
  return 6;
 }

 /*执行SenseLock程序*/
 ret = S4Execute(&ctx, fid, inbuffer, inlen, outbuffer, outlen, outSize);
 if (ret != S4_SUCCESS)
 {   
  S4Close(&ctx);   
  return 7; 
 }   
     
 /*关闭设备*/
 S4Close(&ctx);    
 return 0;  
}    
     
/************************************************************************* 
*dll导出函数
*功能: 调用SenseLock设备进行Hash运算   
*输入参数: 
*BYTE* inbuffer:    指向输入数据内存单元的指针 
*DWORD inlen:输入数据内存单元长度
*BYTE* outbuffer:   指向输出数据内存单元的指针 
*DWORD outlen:      输出数据内存单元长度
*DWORD* outSize:    输出数据的实际使用长度     
*输出值:   
*int :返回0为调用成功,返回非0为调用失败
**************************************************************************/
int SenseLock_Hash(BYTE *inbuffer,DWORD inlen,BYTE * outbuffer,DWORD outlen,DWORD* outSize)     
{    
 return call_sense4("d001", inbuffer, inlen,outbuffer,outlen,outSize);     
}    
     
/************************************************************************* 
*dll导出函数
*功能: 调用SenseLock设备进行TDES运算   
*输入参数: 
*BYTE* inbuffer:    指向输入数据内存单元的指针 
*DWORD inlen:输入数据内存单元长度
*BYTE* outbuffer:   指向输出数据内存单元的指针 
*DWORD outlen:      输出数据内存单元长度
*DWORD* outSize:    输出数据的实际使用长度     
*输出值:   
*int :返回0为调用成功,返回非0为调用失败
**************************************************************************/
int SenseLock_TDES(BYTE *inbuffer,DWORD inlen,BYTE * outbuffer,DWORD outlen,DWORD* outSize)     
{    
 return call_sense4("d002", inbuffer, inlen,outbuffer,outlen,outSize);     
}    
     
/************************************************************************* 
*dll导出函数
*功能: 调用SenseLock设备进行加密运算,先TDES,再Hash 
*输入参数: 
*BYTE* inbuffer:    指向输入数据内存单元的指针 
*DWORD inlen:输入数据内存单元长度
*BYTE* outbuffer:   指向输出数据内存单元的指针 
*DWORD outlen:      输出数据内存单元长度
*DWORD* outSize:    输出数据的实际使用长度     
*输出值:   
*int :返回0为调用成功,返回非0为调用失败
**************************************************************************/
int SenseLock_TDESHash(BYTE *inbuffer,DWORD inlen,BYTE * outbuffer,DWORD outlen,DWORD* outSize) 
{    
 return call_sense4("d003", inbuffer, inlen,outbuffer,outlen,outSize);     
}    
     
#ifdef _MANAGED    
#pragma managed(pop)
#endif


c#调用vc dll
1.添加一个c#项目,建一个窗体。拉3个文本框,一个按钮过来。
2.添加dll函数声明

/// <summary>    
/// SenseLock hash加密方法声明 
/// </summary>   
/// <param name="pbInData">输入数据,明文</param>   
/// <param name="inLen">数据数据长度</param> 
/// <param name="pbOutData">输出数据,密文</param>  
/// <param name="outLen">输出数据长度</param>
/// <param name="iOsutSize">输出数据实际使用长度</param>   
/// <returns>返回0为调用成功,返回非0为调用失败</returns>  
[DllImport("SenseLockVC.dll", CharSet = CharSet.Auto)]     
public static extern int SenseLock_Hash(IntPtr pbInData, int inLen, IntPtr pbOutData, int outLen, IntPtr iOsutSize);

3.在按钮的clikck事件中写代码:
/// <summary>   
/// hash 算法   
/// </summary>  
/// <param name="sender"></param>    
/// <param name="e"></param>  
private void Btn_Hash_Click(object sender, EventArgs e)   

    this.TxtResult.Text = ""; 
    this.TxtResult.Text = ""; 
  
    // UserName + Password    
    string c = this.TxtUserName.Text.Trim() + this.TxtPassword.Text.Trim();    
    byte[] bplainData = Encoding.Unicode.GetBytes(c);     
  
    //数据初始化,申请内存    
    //输入数据  
    IntPtr pbInData = Marshal.AllocHGlobal(bplainData.Length);   
    Marshal.Copy(bplainData, 0, pbInData, bplainData.Length);    
    //输出数据内存单元 
    IntPtr pbOutData = Marshal.AllocHGlobal(OUT_HASH_DATA_LENGTH);
  
    //数据数据的实际大小
    IntPtr iOutSize = Marshal.AllocHGlobal(sizeof(int));  
  
    //调用SenseLock    
    int iReturn = SenseLock.SenseLock_Hash(pbInData, bplainData.Length, pbOutData, OUT_HASH_DATA_LENGTH, iOutSize);
  
    this.TxtReturn.Text = iReturn.ToString();
    if (iReturn == 0 )
    { //处理返回结果
      byte[] bResult = new byte[OUT_HASH_DATA_LENGTH];
      Marshal.Copy(pbOutData, bResult, 0, OUT_HASH_DATA_LENGTH);
      this.TxtResult.Text = Convert.ToBase64String(bResult);
    }
    //释放内存
   Marshal.FreeHGlobal(pbInData);
   Marshal.FreeHGlobal(pbOutData);
   Marshal.FreeHGlobal(iOutSize);