/* ---------------------------------------------------------------- * 功 能: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); }
/* ---------------------------------------------------------------- * 功 能: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)); }
/* ---------------------------------------------------------------- * 功 能: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 ; }
void cal_dedes(unsigned char *key, unsigned char *text, unsigned char *mtext) { _DES(key, text, mtext); }
/* * 函数功能: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; }
/* * 函数功能: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; }