文章目录
前言
- 本文主要参照国家密码行业标准GM/T 0016-2012《智能密码钥匙应用接口规范》。
- 《规范》规定了基于PKI密码体制的智能密码要是密码应用接口,描述了密码应用接口的函数、数据类型、参数的定义和设备的安全要求。
智能密码钥匙介绍
术语和定义
- 应用:包括容器、设备认证密钥和文件的一种结构,具备独立的权限管理。
- 容器:密码设备中用于保存密钥所划分的唯一性存储空间。
- 设备:将智能密码钥匙统称为设备。
层次关系
- 智能密码钥匙密码应用接口位于智能密码钥匙应用程序和智能密码钥匙设备驱动之间。
- 一个设备中存在设备认证密钥和多个应用,应用之间相互独立。
- 一个应用中有PIN码、文件和多个容器。容器内部有加密公私钥对(加密证书)、签名公私钥对(签名证书)、会话密钥等。
接口测试用例
代码如下(示例):
int _tmain(int argc, _TCHAR* argv[])
{
//返回值
ULONG ret = 0;
//加载动态链接库
HMODULE hModule;
ret = Load(_T("***.dll"), &hModule);//loadlibrary
if (ret != 0)
{
printf("加载**库失败\n");
getchar();
return 0;
}
//设备面操作
DEVHANDLE hDev= NULL;//设备句柄
char szNameList[1000] = {0};
ULONG ulSize = 1000;
printf("\n..........枚举设备...........\n");
ret = SKF_EnumDev(1,szNameList,&ulSize);
if( ret != SAR_OK)
{
printf("SKF_EnumDev失败,错误代码为:%02x",ret);
getchar();
return 0;
}
printf("枚举成功\n");
printf("deviceName = %s;sLen=%d\n",szNameList,ulSize);
printf("\n..........连接设备...........\n");
ret = SKF_ConnectDev(sNameList, &hDev);
if(ret != SAR_OK)
{
printf("连接设备出错,错误代码为:%02x",ret);
getchar();
return 0;
}
printf("\n..........获取设备信息...........\n");
DEVINFO devInfo = {0};
ret = SKF_GetDevInfo(hDev, &devInfo);
if(ret != SAR_OK)
{
printf("获取设备信息,错误代码为:%02x",ret);
getchar();
return 0;
}
printf("deviceSN=%s\n", devInfo.SerialNumber);
//应用面操作
HAPPLICATION hApp = NULL;//应用句柄
char szAppName[1000] = {0};
ulSize = 1000;
printf("\n..........枚举应用...........\n");
szAppName = (char *)malloc(ulSize);
memset(szAppName, 0 , ulSize);
rv = SKF_EnumApplication(hDev,szAppName,&ulSize);
if(ret != SAR_OK )
{
printf("枚举应用失败,错误代码为:%02x",ret);
getchar();
return 0;
}
//输出应用名字
char* p = NULL;
p = szAppName;
while(*p != '\0')
{
printf("应用名称为:\n%s\n",p);
//指向下一个
p += strlen(p);
p++;
}
printf("枚举应用成功,应用名称为:\n%s\n",szAppName);
printf("\n..........打开应用...........\n");
ret = SKF_OpenApplication(hDev,szAppName, &hApp);
if(ret != SAR_OK )
{
printf("打开应用失败,错误代码为:%02x",ret);
getchar();
return 0;
}
printf("打开应用成功\n");
printf("\n..........验证口令...........\n");
char Pin[50]={0};
ULONG ulRetryCount = 0;
ret = SKF_VerifyPIN(hApp, 1, (LPSTR)"******", &ulRetryCount);
if(ret != SAR_OK)
{
printf("认证用户口令错误,错误代码为:%02x,重试次数:%d\n",rv,ulRetryCount);
getchar();
return 0;
}
printf("认证用户口令成功\n");
printf("\n..........修改口令...........\n");
ret = SKF_ChangePIN(hApp, USER_TYPE, (LPSTR)"**", (LPSTR)"***",&ulRetryCount);
if(rv != SAR_OK)
{
printf("SKF_ChangePIN错误,错误代码为:%02x,重试次数:%d\n",rv,ulRetryCount);
getchar();
return 0;
}
printf("修改口令成功\n");
//容器面操作
HCONTAINER hCon = NULL;//容器句柄
char *szContainerList[1000] = {0};
ulSize = 1000;
printf("\n..........枚举容器...........\n");
ret = SKF_EnumContainer(hApp, (LPSTR)szContainerList, &ulSize);
if (ret != SAR_OK)
{
printf("枚举容器失败,错误代码为:%02x",rv);
getchar();
return 0;
}
//输出容器名字
char* p1 = NULL;
p1 = szContainerList;
while(*p1 != '\0')
{
printf("容器名称为:\n%s\n",p1);
//指向下一个
p1 += strlen(p1);
p1++;
}
printf("\n..........打开容器zz...........\n");
ret = SKF_OpenContainer(hApplication, "zz", &hCon);
if (ret != SAR_OK)
{
printf("打开容器失败,错误代码为:%02x",ret);
return 0;
}
printf("打开zz容器成功\n");
printf("\n..........导出容器zz中证书...........\n");
BYTE pbCert[3000] = {0};
ULONG ulCertLen = 3000;
ret = SKF_ExportCertificate(hCon,1,pbCert,&ulCertLen);
if (ret != 0)
{
printf("导出证书失败,错误代码为:%02x",ret);
getchar();
return 0;
}
char B64Cert[3000] = {0};
unsigned long B64CertLen = 3000;
ret = B64ENCODE(pbCert, ulCertLen, B64Cert, &B64CertLen, 0);//BASE64格式转换
printf("%s\n",B64Cert);
getchar();
return 0;
}