Пример #1
0
/* ----------------------------------------------------------------
 * 功    能:TRIPLE_DES解密
 * 输入参数:uszKey     解密密钥
 *           uszSrc     解密前数据
 * 输出参数:uszDest    解密后数据
 * 返 回 值:
 * 作    者:
 * 日    期:
 * 调用说明:
 * 修改日志:修改日期    修改者      修改内容简述
 * ----------------------------------------------------------------
 */
void  _TriDES(unsigned char *uszKey ,unsigned char *uszSrc,
	      unsigned char *uszDest)
{
    char buff[17];
    char buf[17];
    
    _DES(uszKey, uszSrc, (unsigned char*)buff);
    DES(uszKey+8, (unsigned char*)buff, (unsigned char*)buf);
    _DES(uszKey, (unsigned char*)buf, uszDest);
}
Пример #2
0
/* ----------------------------------------------------------------
 * 功    能:ANSI X9.8    解密模块
 * 输入参数:uszKey       解密密钥明文
 *           szPan        账号
 *           uszPasswd     密码密文
 *           iFlag        算法标识: 采用DES或3DES
 * 输出参数:uszResult    采用ansi98解密后的密码明文
 * 返 回 值:-1  解密失败;  0  成功
 * 作    者:
 * 日    期:
 * 调用说明:
 * 修改日志:修改日期    修改者      修改内容简述
 * ----------------------------------------------------------------
 */
int _ANSIX98(unsigned char *uszKey, char *szPan, unsigned char *uszPwd,
             int iFlag, unsigned char *uszResult)
{
    unsigned char  a_value [ 17 ];
    
    if (iFlag == TRIPLE_DES)
    {
        _TriDES(uszKey, uszPwd, a_value);
    }
    else
    {
        _DES(uszKey, uszPwd, a_value);
    }
    
    return(_A_(a_value, szPan, uszResult));
}
Пример #3
0
/* ----------------------------------------------------------------
 * 功    能:ANSI X9.19    计算MAc
 *  TMP1 = DES ( DES (A, KeyL ) ^ ( A + 8 ) ... ), KeyL )
 *  TMP2 = _DES( TMP1, KeyR )
 *  MAC  = DES( TMP2, KeyL )
 * 输入参数:uszMacKey      计算MAC的密钥
 *           uszBuf         用于计算MAc的报文
 *           iLen          报文长度
 * 输出参数:uszMac         计算结果MAc值(64bit)
 * 返 回 值:
 * 作    者:
 * 日    期:
 * 调用说明:
 * 修改日志:修改日期    修改者      修改内容简述
 * ----------------------------------------------------------------
 */
void ANSIX919(unsigned char *uszMacKey, unsigned char *uszBuf, int iLen, 
              unsigned char *uszMac)
{
    int   i, j;
    char  tmp[20];

    if (iLen <= 0)
    {
        WriteLog(ERROR, "Invalid argument[iLen=%d]", iLen);
        return ;
    }

    memset(uszMac, '\0', 8);
    
    for (i = 0; i < iLen; i += 8) 
    {
        /* right-justified with append 0x00 */
        if ((iLen - i) < 8) 
        {
            memset(tmp, '\0', 8);
            memcpy(tmp, uszBuf + i, iLen - i);
            for (j = 0; j < 8; j ++) 
            {
                uszMac[j] ^= tmp[j];
            }
        }
        else 
        {
            for (j = 0; j < 8; j ++) 
            {
                uszMac[j] ^= uszBuf[i+j];
            }
        }
        
        DES(uszMacKey, uszMac, uszMac);
    }
    
    _DES(uszMacKey+8, uszMac, uszMac);
    DES(uszMacKey, uszMac, uszMac);
    
    return ;
}
Пример #4
0
void cal_dedes(unsigned char *key, unsigned char *text, unsigned char *mtext)
{
	_DES(key, text, mtext);
}
Пример #5
0
/*
 * 函数功能:IC密钥卡发行
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:NORMAL     ―― 成功
 *           EXCEPTION  ―― 失败
 */
int	PubICCreateKey(void)
{
	unsigned char ucSedBuf[256],ucRecBuf[256],szBuf[4096];
	unsigned int uiRetLen;
   	int i, j;
	CARDHEADER stCardHead;
	KEYREC stKeyRec;
	unsigned char szKeyPwd[9],ucTEK1[17],ucTEK2[17],ucTMK[17],ucTMK1[17],ucTMK2[17],chLRCValue, chCheckvalue[9], kyLRCValue;
	unsigned char  ucRandom[5], ucCardMonKey[17], ucMac[9], ucEncryptData[33];
	int nKeyNum;
	ET_DATETIME tDateTime;
	char szBuffer[100], cRet;

	EA_vCls();
	if ( PubOpenUserICCardDev () != NORMAL )
		return EXCEPTION;

	PubDisplayInv(1, "IC密钥卡发行");
	PubDisplayCen(2, "请插入密钥IC卡");
    PubDisplayCen(3, "按<取消>退出");
    while(1)
    {
      	if ( PubUserICCardIn() == NORMAL )
       		break;
       	if (EA_ucKBHit () == EM_key_HIT)
		{
			if (PubuiInkey (1) == CANCEL)
			{
				return EXCEPTION;
			}
		}
    }
	if ( PubUserICCardPowerUp() != NORMAL )
		return EXCEPTION;

	BUFCLR(ucCardMonKey);		//卡片主控密钥默认是16个0x00

	PubClearAll();
	PubDisplay(2,"请输入密钥卡密码");
	PubKeyOff();	
	BUFCLR(szBuffer);
	cRet = PubGetAStr(3,BIGFONT,szBuffer,8);
	PubKeyOn();
	if (cRet != NORMAL) 
	{
		return EXCEPTION;
	}
	strcpy(szKeyPwd, szBuffer);

	//写卡时间做为一级转加密密钥(POS时间后补0xFF0xFF)
	BUFCLR(ucTEK1);	
	EA_ucGetDateTime (&tDateTime);
	sprintf (szBuffer, "%4d%02d%02d%02d%02d%02d", tDateTime.usYear, tDateTime.ucMonth,
			 tDateTime.ucDay,tDateTime.ucHour,tDateTime.ucMinute,tDateTime.ucSecond);
	memset(ucTEK1, 0xff, 16);
	memcpy (ucTEK1, szBuffer, 14);

	//手工输入的密码做为二级转加密密钥
	BUFCLR(ucTEK2);
	memset(ucTEK2, 0xff, 8);
	memcpy(ucTEK2, szKeyPwd, strlen(szKeyPwd));


	//获取随机数
	if ( ProICCComm1 ("GET CHALLENGE",CPU_CARD, 0x00, 0x84, 0x00, 0x00, 0x00, ucSedBuf,
					0x04, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;
	memcpy(ucRandom,ucRecBuf,4);

	//外部内证
	BUFCLR(szBuf);
	memcpy(szBuf, ucRandom, 4);
	DES(ucCardMonKey, szBuf, ucSedBuf);
	if ( ProICCComm1 ("EXT AUTH",CPU_CARD, 0x00, 0x82, 0x00, 0x00, 0x08, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	//擦除目录
	if ( ProICCComm1 ("CLEAR MF",CPU_CARD, 0x80, 0xee, 0x00, 0x00, 0x00, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00",
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	//建立安全文件
	memcpy(ucSedBuf, "\x1E\x00\x00\x01\x00\xF0\xF0\x00\xFF\x00\xFF", 11);
	if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	//写入MF下密钥
	memcpy(ucSedBuf, "\x39\xF0\xF0\x33\x02", 5);
	memcpy(ucSedBuf+5, ucCardMonKey, 16);
	if ( ProICCComm1 ("WRITE KEY",CPU_CARD, 0x80, 0xd4, 0x01, 0x00, 0x15, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	//创建卡信息记录文件
	memcpy(ucSedBuf, "\x00\x00\x03\x00\x20\xF0\xF0\x03\x00\xFF\x00", 11);
	if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	//创建密钥信息记录文件
	memcpy(ucSedBuf, "\x00\x00\x02\x08\x00\xF0\xF0\x02\x00\xFF\x00", 11);
	if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00",
				0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	//计算密钥的密文
	BUFCLR(ucEncryptData);
	memcpy(ucEncryptData, "\x13\x48\x03\x00", 4);
	memcpy(ucEncryptData+4, ucTEK1, 16);
	memcpy(ucEncryptData+20, "\x80\x00\x00\x00", 4);
	DES(ucCardMonKey, ucEncryptData, ucEncryptData);
	_DES(ucCardMonKey+8, ucEncryptData, ucEncryptData);
	DES(ucCardMonKey, ucEncryptData, ucEncryptData);
	DES(ucCardMonKey, ucEncryptData+8, ucEncryptData+8);
	_DES(ucCardMonKey+8, ucEncryptData+8, ucEncryptData+8);
	DES(ucCardMonKey, ucEncryptData+8, ucEncryptData+8);
	DES(ucCardMonKey, ucEncryptData+16, ucEncryptData+16);
	_DES(ucCardMonKey+8, ucEncryptData+16, ucEncryptData+16);
	DES(ucCardMonKey, ucEncryptData+16, ucEncryptData+16);

	//获取随机数
	BUFCLR(ucRecBuf);
	if ( ProICCComm1 ("GET CHALLENGE",CPU_CARD, 0x00, 0x84, 0x00, 0x00, 0x00, ucSedBuf,
					0x04, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;
	memcpy(ucRandom,ucRecBuf,4);

	//计算MAC
	BUFCLR(ucMac);
	memcpy(ucMac, ucRandom, 4);
	BUFCLR(ucSedBuf);
	memcpy(ucSedBuf, "\x84\xd4\x00\x00\x1c", 5);
	memcpy(ucSedBuf+5, ucEncryptData, 24);
	memcpy(ucSedBuf+29, "\x80\x00\x00", 3);
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 8; j++)
		{
			ucMac[j] ^= ucSedBuf[i * 8 + j];
		}
		DES(ucCardMonKey, ucMac, ucMac);
	}
	_DES(ucCardMonKey+8, ucMac, ucMac);
	DES(ucCardMonKey, ucMac, ucMac);

	//写密钥
	memcpy(ucSedBuf, ucEncryptData, 24);
	memcpy(ucSedBuf+24, ucMac, 4);
	if ( ProICCComm1 ("WRITE KEY",CPU_CARD, 0x84, 0xd4, 0x00, 0x00, 0x1c, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	//写卡信息文件
	BUFCLR(szBuffer);
	DES(ucTEK2, szBuffer, chCheckvalue);
	memset(&stCardHead, 0, sizeof(CARDHEADER));
	stCardHead.KeyNum[0] = 0x00;				//密钥数量 根据实际情况填写 最大66条 在此做为测试只写一条
	stCardHead.KeyNum[1] = 0x01;
	memcpy(stCardHead.chExpireDate, "\x20\x99\x12\x31", 4);//有效期
	memset(stCardHead.chReserved, 0xff, 16);
	memcpy(stCardHead.chCheckvalue, chCheckvalue, 4);
	memcpy(szBuf, &stCardHead, 27);
	chLRCValue = 0;
	for(i=0;i<26;i++)
		chLRCValue ^= szBuf[i];
	stCardHead.chLRCValue = chLRCValue;
	if ( ProICCComm1 ("DF3选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x03",
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;
	BUFCLR(ucSedBuf);
	memcpy(ucSedBuf, &stCardHead, 31);
	if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, 0x00, 0x00, 0x1b, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	if ( ProICCComm1 ("DF2选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x02",
				0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1];
	for(i=0; i<nKeyNum; i++)
	{
		BUFCLR(ucTMK);				//终端主密钥明文 根据实际情况填写 在此做为测试固定8个0x31 8个0x32
		memset(ucTMK, 0x31, 8);
		memset(ucTMK+8, 0x32, 8);

		//初始化加密指令
		if ( ProICCComm1 ("INIT FOR DES",CPU_CARD, 0x80, 0x1a, 0x08, 0x03, 0x00, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
			return EXCEPTION;

		//加密
		memcpy(ucSedBuf, ucTMK, 16);
		if ( ProICCComm1 ("DESCRYPT",CPU_CARD, 0x80, 0xfa, 0x00, 0x00, 0x10, ucSedBuf,
					0x10, ucRecBuf, &uiRetLen) != NORMAL )
			return EXCEPTION;
		memcpy(ucTMK1, ucRecBuf, 16);

		//使用手工输入的密码加密,生成二级转加密密钥
		BUFCLR(ucTMK2);
		DES(ucTEK2, ucTMK1, ucTMK2);
		DES(ucTEK2, ucTMK1+8, ucTMK2+8);

		//写密钥信息文件
		nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1];
		memset(&stKeyRec, 0, sizeof(stKeyRec));
		stKeyRec.kyIndex = 0x00;		//密钥索引 默认值为0x00 实际并没有使用
		stKeyRec.kyNum = 0x01;			//可用次数 0-9 做为预留值 暂时没有使用
		PubAscToHex(stKeyRec.kyMechID, "123456789111115F", 16, 0);	//商户号 根据实际情况填写 记住后补F 在此做为测试
		PubAscToHex(stKeyRec.kyTermID, "11115010", 8, 0);			//终端号 根据实际情况填写 在此做为测试
		memcpy(stKeyRec.kyEncryptMKey, ucTMK2, 16);		//密钥密文
		BUFCLR(szBuf);
		memcpy(szBuf, &stKeyRec, 31);
		kyLRCValue = 0;
		for(i=0;i<29;i++)
			kyLRCValue ^= szBuf[i];
		stKeyRec.kyLRCValue = kyLRCValue;			//校验位
		memcpy(ucSedBuf, &stKeyRec, 31);
		if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, 0x00, 0x00, 0x1f, ucSedBuf,
						0x00, ucRecBuf, &uiRetLen) != NORMAL )
			return EXCEPTION;
	}

	EA_ucCloseDevice (&gbhdlUserCard);

	EA_vCls();
	PubDisplay(2, "发卡成功!");
	PubDisplay(3, "密钥总数:%d", nKeyNum);
	PubuiInkey(20);
	return NORMAL;
}
Пример #6
0
/*
 * 函数功能:IC卡下载密钥
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:NORMAL     ―― 成功
 *           EXCEPTION  ―― 失败
 */
int	PubICDownKey(void)
{
	unsigned char ucSedBuf[256],ucRecBuf[256],szBuf[4096];
	unsigned int uiRetLen,uiRet;
	unsigned char Cp1,Cp2,Cle,CFlagGetKey;
	int len;
	char szGetBuffer[30],szGetBuffer1[30],szGetBuffer2[30],szGetBuffer3[30];
    int i, nBufSize;
	CARDHEADER stCardHead;
	KEYREC stKeyRec;
	unsigned char szKeyPwd[9],ucTEK2[17],ucTMK[17],ucTMK1[17],chLRCValue, chCheckvalue[9], kyLRCValue;
	int nKeyNum, nKeyLen;
	ET_DATETIME tDateTime;	
	char szBuffer[100], cRet;
	int nTmpFlag, nIndex = 5;
	DevHandle phPinpad;

	EA_vCls();
	PubDisplayInv(1, "IC卡导入密钥");
	PubDisplay(2, "主密钥索引号(0-31)");
	//PubDisplay(3, "[%d]",nIndex);
	nTmpFlag = 1;
	do
	{
		BUFCLR(szBuffer);
		cRet = PubGetNStr(4, 0, szBuffer, 2);
		if (cRet == CANCELED||cRet == APPTIMEOUT)
		{
			nTmpFlag = 0;
			break;
		}
		if (strlen(szBuffer) > 2)
			continue;
		nIndex = atoi(szBuffer);
	}
	while (nIndex > 31);
	if (nTmpFlag == 0)
		return EXCEPTION;
	PubGetBankcDesType(&cDesType);	
	
	CFlagGetKey = NO;
	EA_vCls();
	if ( PubOpenUserICCardDev () != NORMAL )
		return EXCEPTION;
	//EA_vCls();
	PubDisplayInv(1, "IC卡导入密钥");
	PubDisplayCen(2, "请插入密钥IC卡");
    PubDisplayCen(3, "按<取消>退出");
    while(1)
    {
      	if ( PubUserICCardIn() == NORMAL )
       		break;
       	if (EA_ucKBHit () == EM_key_HIT)
		{
			if (PubuiInkey (1) == CANCEL)
			{
				return EXCEPTION;
			}
		}
    }
	if ( PubUserICCardPowerUp() != NORMAL )
		return EXCEPTION;

	if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00",
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	if ( ProICCComm1 ("DF3选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x03",
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	if ( ProICCComm1 ("READ BINARY",CPU_CARD, 0x00, 0xb0, 0x83, 0x00, 0x00, ucSedBuf,
				0x1b, ucRecBuf, &uiRetLen)!= NORMAL )
		return EXCEPTION;
	memcpy(&stCardHead, ucRecBuf, 27);
	chLRCValue = 0;
	for(i=0;i<26;i++)
		chLRCValue ^= ucRecBuf[i];
	if(chLRCValue != stCardHead.chLRCValue)
	{
		PubClearAll();
		PubDisplayCen(2, "IC卡错误");
		PubuiInkey(20);
		return EXCEPTION;
	}
	EA_ucGetDateTime (&tDateTime);
	sprintf (szBuffer, "%4d%02d%02d", tDateTime.usYear, tDateTime.ucMonth,
			 tDateTime.ucDay);
	PubAscToHex (szGetBuffer, szBuffer, 8, 0);
	if(memcmp(stCardHead.chExpireDate, szGetBuffer, 4) < 0)
	{
		PubClearAll();
		PubDisplayCen(2, "此卡已过期");
		PubuiInkey(20);
		return EXCEPTION;
	}
		
	if ( ProICCComm1 ("DF2选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x02",
				0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;

	nBufSize = sizeof(szGetBuffer);
	BUFCLR(szGetBuffer);
    ASSERT_NORMAL(PubGetBankszCust(szGetBuffer, nBufSize));
	nBufSize = sizeof(szGetBuffer);
	BUFCLR(szGetBuffer1);
    ASSERT_NORMAL(PubGetBankszTerminal(szGetBuffer1, nBufSize));
    	
	strcat(szGetBuffer, "F");	//商户号是右补F
	PubAscToHex(szGetBuffer2, szGetBuffer, 16, 0);
	PubAscToHex(szGetBuffer3, szGetBuffer1, 8, 0);

	nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1];
	BUFCLR(szBuf);
	i=0;
	while(1)
	{
		len = i * 31;
			
		Cp1 = (uchar)(len/256);
		Cp2 = (uchar)(len%256);
		Cle = 31;
		if ( ProICCComm1 ("READ BINARY",CPU_CARD, 0x00, 0xb0, Cp1, Cp2, 0x00, ucSedBuf,
					Cle, ucRecBuf, &uiRetLen)!= NORMAL )
			return EXCEPTION;
		if (CARD_SW1 == 0x6B )
			break;
		memcpy(&stKeyRec, ucRecBuf, 31);
		if(!memcmp(stKeyRec.kyMechID,szGetBuffer2,8) && !memcmp(stKeyRec.kyTermID,szGetBuffer3,4))
		{
			CFlagGetKey = YES;
			break;
		}
		i++;
		if(i > nKeyNum)	
			break;
	}
	if ( CFlagGetKey == NO )
	{
		PubClearAll();
		PubDisplayCen(2, "主密钥未找到");
        PubuiInkey (20);
        return EXCEPTION;
	}
	// 银商规范修改,这个值无效,不用判断了。
// 	if(stKeyRec.kyNum < 1)
// 	{
// 		PubClearAll();
// 		PubDisplayCen(2, "该密钥已无法使用");
// 		PubuiInkey(20);
// 		return EXCEPTION;
// 	}
	BUFCLR(szBuf);
	memcpy(szBuf, &stKeyRec, 31);
	kyLRCValue = 0;
	for(i=0;i<29;i++)
		kyLRCValue ^= szBuf[i];
	if(kyLRCValue != stKeyRec.kyLRCValue)
	{
/*银商总公司沈进要求不写卡
		//可用次数减1
		stKeyRec.kyNum--;
		memcpy(ucSedBuf, &stKeyRec, 31);
		if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
			return EXCEPTION;
*/
		PubClearAll();
		PubDisplayCen(2, "主密钥有误");
		PubuiInkey(20);
		return EXCEPTION;
	}
	
	PubClearAll();
	PubDisplay(2,"请输入密钥卡密码");
	PubKeyOff();	
	BUFCLR(szBuffer);
	uiRet = PubGetAStr(3,BIGFONT,szBuffer,8);
	PubKeyOn();
	if (uiRet != NORMAL) 
	{
		return EXCEPTION;
	}
	strcpy(szKeyPwd, szBuffer);

	BUFCLR(ucTEK2);
	memset(ucTEK2, 0xff, 8);
	memcpy(ucTEK2, szKeyPwd, strlen(szKeyPwd));
	BUFCLR(szBuffer);
	DES(ucTEK2, szBuffer, chCheckvalue);
	if(memcmp(stCardHead.chCheckvalue, chCheckvalue, 4))
	{
/*银商总公司沈进要求不写卡
		//可用次数减1
		stKeyRec.kyNum--;
		memcpy(ucSedBuf, &stKeyRec, 31);
		if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf,
					0x00, ucRecBuf, &uiRetLen) != NORMAL )
			return EXCEPTION;
*/
		PubClearAll();
		PubDisplayCen(2, "密码错误");
		PubuiInkey(20);
		return EXCEPTION;
	}

	//使用手工输入的密码对IC卡中存在的二级转加密主密钥TMK2进行Des解密,获得TMK1
	BUFCLR(ucTMK1);
	_DES(ucTEK2, stKeyRec.kyEncryptMKey, ucTMK1);
	_DES(ucTEK2, stKeyRec.kyEncryptMKey+8, ucTMK1+8);

	//初始化加密指令
	if ( ProICCComm1 ("INIT FOR DES",CPU_CARD, 0x80, 0x1a, 0x08, 0x03, 0x00, ucSedBuf,
				0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;
	
	//解密
	if ( ProICCComm1 ("DESCRYPT",CPU_CARD, 0x80, 0xfa, 0x80, 0x00, 0x10, ucTMK1,
				0x10, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;
	memcpy(ucTMK, ucRecBuf, 16);

	if (PubOpenDevice("PINPAD", EM_io_EPP, &phPinpad) != EM_SUCCESS)
    {
        PubDisplay(2, "密码键盘打开失败!");
        EA_vBeepMs(50);
        return EXCEPTION;;
    }

	nKeyLen = 16;    
    while (PubLoadKey(phPinpad, EM_pin_MASTERKEY, nIndex, nKeyLen, ucTMK) != NORMAL)
    {
        PubDisplay(2, "请接好密码键盘!");
        EA_vBeepMs(50);
        PubuiInkey(1);
    }
	EA_ucCloseDevice(&phPinpad);
	PubSetBankcDesType(DES3);			//设定密钥类型为3DES

/*银商总公司沈进要求不写卡
	//可用次数置0
	stKeyRec.kyNum=0;
	memcpy(ucSedBuf, &stKeyRec, 31);
	if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf,
				0x00, ucRecBuf, &uiRetLen) != NORMAL )
		return EXCEPTION;
*/
	EA_ucCloseDevice (&gbhdlUserCard);

	EA_vCls();
	PubDisplay(2, "主密钥导入成功!");
	PubuiInkey(20);
	return NORMAL;
}