硬件动态令牌特性动态口令生成算法C语言实现用例计算输入输出用例Word格式.docx
《硬件动态令牌特性动态口令生成算法C语言实现用例计算输入输出用例Word格式.docx》由会员分享,可在线阅读,更多相关《硬件动态令牌特性动态口令生成算法C语言实现用例计算输入输出用例Word格式.docx(29页珍藏版)》请在冰点文库上搜索。
遵守GB/T4208-2008中IP44的要求。
A.1.8
标记和印刷
1000
使用GB/T2423.53-2005,试验液体:
人工合成汗液,力的大小:
次。
产品必须具备标记文字为:
“序列号”和“有效期”。
1N±
0.2N,循环次数:
A.1.9
振动
使用GB/T2423.10-2008,严酷等级选择频率范围:
持续时间:
60min。
10Hz到
300Hz,振动幅值:
3.5mm,
A.1.10
静电放电
不低于GB/T17626.2-2006中试验等级3的标准,即满足外壳端口接触放电±
6kV,空气放电±
8kV。
A.1.11试验过程中试验样品是否处于工作状态的判断标准
样品带电运行,目视检查,提供最少12个显示相同动态口令的样品,6个一组为参与
试验样品,6个一组为不参与试验样品,参与试验的样品显示动态口令与不参与试验样品一致即为合格。
A.2令牌安全特性
A.2.1种子密钥安全
种子密钥为令牌重要安全要素,令牌必须保证产品内的种子密钥的完整性,且种子密钥为单向导入令牌(或在令牌内生成),种子密钥不能被导出产品外部。
令牌必须拥有种子密钥的保护功能。
令牌种子密钥加密、存储、使用在令牌芯片的安全区域内实现。
A.2.2令牌芯片安全
本标准涉及的令牌芯片,应是国家密码管理局批准产品型号证书的安全芯片。
A.2.3
令牌物理安全
令牌具有低电压检测功能。
令牌完成种子密钥导入后,通讯I/O端口应失效,不能再输入或输出信息,包括但不限
于内部参与口令生成运算的K、T、C信息。
令牌应防范通过物理攻击的手段获取设备内的敏感信息,物理攻击的手段包括但不限于
开盖、搭线、复制等。
令牌芯片必须具备令牌掉电后,会自动销毁种子密钥的措施。
令牌芯片应保证种子密钥无法通过外部或内部的方式读出,包括但不限于:
调试接口、
改编的程序。
令牌芯片可防范通过物理攻击的手段获取芯片内的敏感信息,确保种子密钥和算法程序
的安全性。
令牌芯片应具备抵抗旁路攻击的能力,包括但不限于:
抗SPA/DPA攻击能力,抗
SEMA/DEMA攻击能力。
在外部环境发生变化时,令牌芯片不应泄漏敏感信息或影响安全功能。
外部环境的变化包含但不限于:
高低电压、高低温、强光干扰、电磁干扰、紫外线干扰、静电干扰。
A.2.4使用安全
具有数字和功能按键的令牌必须具有PIN保护功能,PIN长度不少于6位,并具有PIN
防暴力穷举功能。
令牌可具有PIN找回功能,即令牌用户如果忘记令牌PIN,可通过安全有
效的环境与机制找回令牌PIN,或对令牌PIN进行重新设置(如远程解PIN)。
PIN输入错误的次数不可超过
5次,若超过,应至少等待
1h
才可继续尝试。
PIN输入超过最大尝试次数的情况不可超过5次,否则令牌应永久锁定,不可再使用。
令牌基本使用寿命为3年,令牌产品最长使用不超过5年。
室温环境下,令牌时间偏差小于2min/年。
A.2.5安全评估
动态令牌产品安全评估遵守以下国标规定:
GB/T18336.1-2008
GB/T18336.2-2008
GB/T18336.3-2008
GB/T21079.1-2007
A
BA
附录B
(资料性附录)
动态口令生成算法C语言实现用例
B.1采用SM3的动态口令生成算法用例
#include<
stdio.h>
string.h>
math.h>
#include"
sm3.h"
sm_dpwd.h"
#ifdef__cplusplus
#defineINLINEinline#else
#defineINLINE#endif
INLINEboolIsBigEndian()
{
unionT
charc[2];
shorts;
};
Tt;
t.s=0x0031;
if(t.c[1]==0x31)
returntrue;
}
returnfalse;
INLINEboolIsLittleEndian()
return!
IsBigEndian();
INLINEuint32Reverse32(uint32x)
return((x&
0x000000ff)<
<
24)
|((x&
0x0000ff00)<
8)
0x00ff0000)>
>
0xff000000)>
24);
INLINEuint64Reverse64(uint64x)
uint32nTemp[3]={0};
memcpy(nTemp+1,&
x,sizeof(uint64));
nTemp[0]=Reverse32(nTemp[2]);
nTemp[1]=Reverse32(nTemp[1]);
return*(uint64*)nTemp;
INLINEsm_wordML(byteX,uint8j)
if(IsBigEndian())
return(sm_word)(X<
(j%32));
else
returnReverse32((sm_word)(X<
(j%32)));
INLINEsm_wordSUM(sm_wordX,sm_wordY)
return(X+Y);
returnReverse32(Reverse32(X)+Reverse32(Y));
intTruncateSM3(INbytepSrc[32],INintnSrcLen,OUTbytepDst[4],INintnDstSize)
if(nSrcLen!
=32||nDstSize<
4)
return-1;
memset(pDst,0,nDstSize);
byte*S=(byte*)pSrc;
sm_wordS1=ML(S[0],24)|ML(S[1],16)|ML(S[2],8)|ML(S[3],0);
sm_wordS2=ML(S[4],24)|ML(S[5],16)|ML(S[6],8)|ML(S[7],0);
sm_wordS3=ML(S[8],24)|ML(S[9],16)|ML(S[10],8)|ML(S[11],0);
sm_wordS4=ML(S[12],24)|ML(S[13],16)|ML(S[14],8)|ML(S[15],0);
sm_wordS5=ML(S[16],24)|ML(S[17],16)|ML(S[18],8)|ML(S[19],0);
sm_wordS6=ML(S[20],24)|ML(S[21],16)|ML(S[22],8)|ML(S[23],0);
sm_wordS7=ML(S[24],24)|ML(S[25],16)|ML(S[26],8)|ML(S[27],0);
sm_wordS8=ML(S[28],24)|ML(S[29],16)|ML(S[30],8)|ML(S[31],0);
sm_wordOD=SUM(SUM(SUM(SUM(SUM(SUM(SUM(S1,S2),S3),S4),S5),S6),S7),S8);
memcpy(pDst,&
OD,sizeof(sm_word));
return0;
#defineSM_DPWD_KEY_LEN_MIN
(128/8)
#defineSM_DPWD_CHALLENGE_LEN_MIN
(4)
#defineSM_DPWD_LEN_MAX
(10)
#defineSM_HASH_OUT_LEN
(32)
intSM3_DPasswd(INbyte*pKey,INintnKeyLen,INuint64*pTime,INuint64*pInterval,INuint32*pCounter,
INchar*pChallenge,INintnGenLen,OUTchar*pDynPwd,INint
nDynPwdSize)
if(pKey==NULL||(pTime==NULL&
&
pCounter==NULL&
pChallenge==NULL)
||pDynPwd==NULL||nKeyLen<
SM_DPWD_KEY_LEN_MIN||nGenLen>
SM_DPWD_LEN_MAX
||(pChallenge!
=NULL&
strlen(pChallenge)<
SM_DPWD_CHALLENGE_LEN_MIN)
||nDynPwdSize<
nGenLen+1)
returnSM_DPWD_PARAM_ERROR;
memset(pDynPwd,0,nDynPwdSize);
//T=To/Tc
if(pTime!
pInterval!
*pInterval!
=0)
*pTime=(*pTime)/(*pInterval);
//Converttobig-endian.if(!
IsBigEndian())
=NULL)
*pTime=Reverse64(*pTime);
if(pCounter!
*pCounter=Reverse32(*pCounter);
int
offset
=0;
byte*
sm_i
=NULL;
byte
sm_o[SM_HASH_OUT_LEN]={0};
sm_i_len
sm_o_len
=sizeof(sm_o);
uint32pwd
={0};
//ID(T|C|Q)Lengthatleast128bits
sm_i_len=(pTime?
sizeof(uint64):
0)+(pCounter?
sizeof(uint32):
0)+(pChallenge?
strlen(pChallenge):
0);
if(sm_i_len<
16)
//FillIDto128bitswith0attheend.sm_i_len=16;
sm_i_len+=nKeyLen;
//AllocateIN-Datamemory.sm_i=newbyte[sm_i_len];
if(sm_i==NULL)
returnSM_DPWD_NO_MEMORY;
memset(sm_i,0,sm_i_len);
//1.KEY|ID(T|C|Q)memcpy(sm_i,pKey,nKeyLen);
offset=nKeyLen;
memcpy(sm_i+offset,pTime,sizeof(uint64));
offset+=sizeof(uint64);
memcpy(sm_i+offset,pCounter,sizeof(uint32));
offset+=sizeof(uint32);
if(pChallenge!
memcpy(sm_i+offset,pChallenge,strlen(pChallenge));
//2.SM3
SM3(sm_i,sm_i_len,sm_o,sm_o_len);
//3.Truncate
TruncateSM3(sm_o,sm_o_len,(byte*)&
pwd,sizeof(pwd));
#ifdef__SM_DBG_OUT
___DInit();
___DAdd("
K:
[%s]\r\n"
___S2M(pKey,nKeyLen));
T:
[%016s]\r\n"
___S2M(pTime,8));
C:
[%08s]\r\n"
___S2M(pCounter,4));
Q:
___S2M(pChallenge,pChallenge==NULL?
0:
strlen(pChallenge)));
SM3-IN:
___S2M(sm_i,sm_i_len));
SM3-OUT:
___S2M(sm_o,sm_o_len));
Cut:
___S2M(&
pwd,sizeof(pwd)));
#endif//__SM_DBG_OUT
//4.MOD
if(!
pwd=Reverse32(pwd);
pwd=pwd%(int)pow(10,nGenLen);
//Output
charszFmt[32]={0};
sprintf(szFmt,"
%%0%dd"
nGenLen);
sprintf(pDynPwd,szFmt,pwd);
delete[]sm_i;
B.2采用SM4的动态口令生成算法用例
sm4.h"
#defineINLINEinline
#else
#defineINLINE
#endif
#ifndefmax
#definemax(a,b)
(((a)>
(b))?
(a):
(b))
#ifndefmin
#definemin(a,b)
(((a)<
intTruncateSM4(INbytepSrc[16],INintnSrcLen,OUTbytepDst[4],INintnDstSize)
=16||nDstSize<
sm_wordS1
=ML(S[0],24)
|ML(S[1],16)
|ML(S[2],8)|ML(S[3],0);
sm_wordS2
=ML(S[4],24)
|ML(S[5],16)
|ML(S[6],8)|ML(S[7],0);
sm_wordS3
=ML(S[8],24)
|ML(S[9],16)
|ML(S[10],8)|ML(S[11],0);
sm_wordS4
=ML(S[12],24)|ML(S[13],16)|ML(S[14],8)|ML(S[15],0);
sm_wordOD=SUM(SUM(SUM(S1,S2),S3),S4);
memcpy(pDst,&
intSM4_DPasswd(INbyte*pKey,INintnKeyLen,INuint64*pTime,INuint64*pInterval,INuint32*pCounter,
sm_buf
sm_k
sm_o[16]={0};
sm_k_len=0;
sm_i_len=0;
sm_o_len=sizeof(sm_o);
//IflengthofKeyisnotmultipleof128bits,extendittomu