// function login_card static int KSAPI login_card(ks_reader_dev_t *dev,ks_card_info_t *card,int sect_no, KS_MF_KEYTYPE keytype,const uint8 *key) { int ret; uint8 mode; if(keytype == MF_KEYA) { mode = 0; } else { mode = 4; } if(!g_dev_hd) return KS_PORT_NOTOPEN; char hex[16]= {0}; bcd2asc(key, 6, hex); ret = RWD.rf_load_key_hex(g_dev_hd,mode,sect_no,hex); // rf_load_key 有bug, 会导致 keya 验证不通过 //unsigned char stuff[7]={0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0}; //ret = RWD.rf_load_key(g_dev_hd,mode,sect_no,stuff); if(ret) { GetErrMsgByErrCode(ret,gErrMsg); return KS_LOGINCARD; } ret = RWD.rf_authentication((int)g_dev_hd,mode,sect_no); if(ret) { GetErrMsgByErrCode(ret,gErrMsg); return KS_LOGINCARD; } return 0; }
void CKeyCreateDlg::OnCreatekey() { CString pinpadno; m_pinpadno.UpdateData(TRUE); m_pinpadno.GetWindowText(pinpadno); if(pinpadno.IsEmpty()) { MessageBox("密码键盘号不能为空, 请输入后再试!", "提示信息", MB_ICONWARNING|MB_OK); return; } // add sunj 2012/07/23 if (pinpadno.GetLength() < 8) { MessageBox("密码键盘号长度错, 请输入8位长数据!", "提示信息", MB_ICONWARNING|MB_OK); return; } if (PubPortTest(gbHandFile) != SUCC) { MessageBox("请确认是否连接密钥母POS!", "提示信息", MB_ICONWARNING|MB_OK); return; } m_btn_createkey.EnableWindow(FALSE); char szLMK1[40], szZMK1[40], szCheckval1[20]; char szLMK2[40], szZMK2[40], szCheckval2[20]; char szLMK3[40], szZMK3[40], szCheckval3[20]; memset(szLMK1, 0x00, sizeof(szLMK1)); memset(szLMK2, 0x00, sizeof(szLMK2)); memset(szLMK3, 0x00, sizeof(szLMK3)); memset(szZMK1, 0x00, sizeof(szZMK1)); memset(szZMK2, 0x00, sizeof(szZMK2)); memset(szZMK3, 0x00, sizeof(szZMK3)); memset(szCheckval1, 0x00, sizeof(szCheckval1)); memset(szCheckval2, 0x00, sizeof(szCheckval2)); memset(szCheckval3, 0x00, sizeof(szCheckval3)); //第一步 调用加密机获取随机终端主密钥 m_key_info.SetWindowText("与加密机通讯, 正在获取终端主密钥..."); int iRet = GetRankTMK(szLMK1, szZMK1, szCheckval1, szLMK2, szZMK2, szCheckval2, szLMK3, szZMK3, szCheckval3); if(iRet == TIMEOUT) { m_key_info.SetWindowText("与加密机通讯超时!"); m_btn_createkey.EnableWindow(TRUE); return; } else if(iRet == FAIL) { m_key_info.SetWindowText("加密机调用错误!"); m_btn_createkey.EnableWindow(TRUE); return; } m_key_info.SetWindowText("加密机调用成功, 获取终端主密钥!"); //第二步 调用加密机解密终端主密钥 char IV[10]; //初始化向量 char Flag = 0; //加解密标识 1 加密, 0 解密 char algorithm = 0; //算法标识 ECB=0 CBC=1 3DES=0 DES=1 char DecryptKey[20]; //解密后的主密钥 char szDecryptTMK[40]; //Asc可见的主密钥 memset(IV, 0x00, sizeof(IV)); memset(DecryptKey, 0x00, sizeof(DecryptKey)); memset(szDecryptTMK, 0x00, sizeof(szDecryptTMK)); m_key_info.SetWindowText("与加密机通讯, 正在Decrypt终端主密钥..."); iRet = DecryptTMK(IV, Flag, algorithm, szZMK1, DecryptKey); // 到底是szLMK1 ,还是szZMK1还需判断 //iRet = DecryptTMK(IV, Flag, algorithm, szLMK1, DecryptKey); if(iRet == TIMEOUT) { m_key_info.SetWindowText("与加密机通讯超时!"); m_btn_createkey.EnableWindow(TRUE); return; } else if(iRet == FAIL) { m_key_info.SetWindowText("加密机调用错误!"); m_btn_createkey.EnableWindow(TRUE); return; } bcd2asc((byte *)szDecryptTMK, (byte *)DecryptKey, 32, 0); m_key_info.SetWindowText("加密机调用成功, Decrypt终端主密钥成功!"); //第三步 保存数据到数据库 char sql[500]; char szTmp[200]; char SAMID[10]; memset(sql, 0x00, sizeof(sql)); memset(szTmp, 0x00, sizeof(szTmp)); memset(SAMID, 0x00, sizeof(SAMID)); memcpy(SAMID, (LPTSTR)(LPCTSTR)pinpadno, 8); strcpy(sql, "insert into T_PHONE_SAMID (SAMID, STATUS, BANKNO, STARTDATE, STOPDATE, ENCNO, D_FLAG, TERMTYPE) "); sprintf(szTmp, "values('%s','0','','20110101','20610316','226000','0','2')", SAMID); strcat(sql, szTmp); iRet = g_DbManager.ExecuteSQL(sql); if(iRet < 1) { g_DbManager.DBClose(); iRet = g_DbManager.DBConnect(); if(iRet != 0) { WriteLog(ERROR_LEVEL, "重新连接数据库失败! 执行SQL命令失败!"); WriteLog(ERROR_LEVEL, sql); g_pKeyServDlg->SetListCtrl(1, "T_PHONE_SAMID表新增记录失败!"); m_key_info.SetWindowText("T_PHONE_SAMID表新增记录失败!"); m_btn_createkey.EnableWindow(TRUE); return; } else { WriteLog(DEBUG_LEVEL, "重新连接数据库成功!"); if(g_DbManager.ExecuteSQL(sql) < 1) { WriteLog(ERROR_LEVEL, sql); g_pKeyServDlg->SetListCtrl(1, "T_PHONE_SAMID表新增记录失败!"); m_key_info.SetWindowText("T_PHONE_SAMID表新增记录失败!"); m_btn_createkey.EnableWindow(TRUE); return; } } } else { WriteLog(DEBUG_LEVEL, "T_PHONE_SAMID表新增记录成功!"); g_pKeyServDlg->SetListCtrl(0, "T_PHONE_SAMID表新增记录成功!"); m_key_info.SetWindowText("T_PHONE_SAMID表新增记录成功!"); } memset(sql, 0x00, sizeof(sql)); memset(szTmp, 0x00, sizeof(szTmp)); strcpy(sql, "insert into T_PHONE_KEY(SAMID, KEK0, KEK1, KEK2, TDK, PIK, MAK, USEINDEX, LOADINDEX, UPTIME, UPFLAG, PCNO, UNPAYFLAG) "); sprintf(szTmp, "values('%s','%s','%s','%s',' ',' ',' ','0','0','20110609','1','000001','1')", SAMID, szLMK1, szLMK2, szLMK3); strcat(sql, szTmp); iRet = g_DbManager.ExecuteSQL(sql); if(iRet < 1) { g_DbManager.DBClose(); iRet = g_DbManager.DBConnect(); if(iRet != 0) { WriteLog(ERROR_LEVEL, "重新连接数据库失败! 执行SQL命令失败!"); WriteLog(ERROR_LEVEL, sql); g_pKeyServDlg->SetListCtrl(1, "T_PHONE_KEY表新增记录失败!"); m_key_info.SetWindowText("T_PHONE_KEY表新增记录失败!"); DelPhoneSamid(SAMID); m_btn_createkey.EnableWindow(TRUE); return; } else { WriteLog(DEBUG_LEVEL, "重新连接数据库成功!"); if(g_DbManager.ExecuteSQL(sql) < 1) { WriteLog(ERROR_LEVEL, sql); g_pKeyServDlg->SetListCtrl(1, "T_PHONE_KEY表新增记录失败!"); m_key_info.SetWindowText("T_PHONE_KEY表新增记录失败!"); DelPhoneSamid(SAMID); m_btn_createkey.EnableWindow(TRUE); return; } } } else { WriteLog(DEBUG_LEVEL, "T_PHONE_KEY表新增记录成功!"); g_pKeyServDlg->SetListCtrl(0, "T_PHONE_KEY表新增记录成功!"); m_key_info.SetWindowText("T_PHONE_KEY表新增记录成功!"); } //第四步 写终端主密钥明文加密后保存到密钥文件中 char EncryptTMK[20]; char szEncryptTMK[40]; char SEK[20]; memset(EncryptTMK, 0x00, sizeof(EncryptTMK)); memset(szEncryptTMK, 0x00, sizeof(szEncryptTMK)); memset(SEK, 0x00, sizeof(SEK)); // modify sunj 2012/07/24 // asc2bcd((byte *)SEK, (byte *)(g_ConfigParam.sek), 32, 0); // memcpy(SEK, "\x01\x23\x45\x67\xAB\xCD\xEF\x1F\x89\x23\x45\xDD\x01\x23\x45\x67", 16); // 为了安全使用内置KEY计算 memcpy(SEK, "\x01\x23\x45\x67\xAB\xCD\xE8\x9F", 8); // end // TriDES( SEK, DecryptKey, EncryptTMK); // TriDES( SEK, DecryptKey+8, EncryptTMK+8 ); LandiDES(SEK, DecryptKey, EncryptTMK); LandiDES(SEK, DecryptKey + 8, EncryptTMK + 8); /* char szEncryptKey[40]; memset(szEncryptKey, 0x00, sizeof(szEncryptKey)); bcd2asc((byte *)szEncryptKey, (byte *)EncryptTMK, 32, 0); */ /* char szEncryptKey[40]; memset(szEncryptKey, 0x00, sizeof(szEncryptKey)); bcd2asc((byte *)szEncryptKey, (byte *)DecryptKey, 32, 0); if(WriteTMKFile(SAMID, szEncryptKey) == SUCC) { WriteLog(DEBUG_LEVEL, "写key文件成功!"); g_pKeyServDlg->SetListCtrl(0, "写key文件成功!"); m_key_info.SetWindowText("写key文件成功!"); } else { WriteLog(DEBUG_LEVEL, "写key文件失败!"); g_pKeyServDlg->SetListCtrl(0, "写key文件失败!"); m_key_info.SetWindowText("写key文件失败!"); m_btn_createkey.EnableWindow(TRUE); return; } */ //第五步 操作串口, 把终端主密钥传送到密钥母POS上 (需要孙军自己加) // 如果下发失败则删除数据库记录 //... if (PubSendIDAndMaster(gbHandFile, (unsigned char *)SAMID, 8, 0) != SUCC) { WriteLog(ERROR_LEVEL, "发送密码键盘ID失败"); // 删除数据库记录 g_pKeyServDlg->SetListCtrl(1, "发送密码键盘ID失败!"); m_key_info.SetWindowText("发送密码键盘ID失败!"); DelPhoneSamid(SAMID); DelPhoneKey(SAMID); m_btn_createkey.EnableWindow(TRUE); return; } if (PubSendIDAndMaster(gbHandFile, (unsigned char *)EncryptTMK, 16, 1) != SUCC) { WriteLog(ERROR_LEVEL, "发送主密钥失败"); // 删除数据库记录 DelPhoneSamid(SAMID); DelPhoneKey(SAMID); g_pKeyServDlg->SetListCtrl(1, "发送主密钥失败!"); m_key_info.SetWindowText("发送主密钥失败!"); m_btn_createkey.EnableWindow(TRUE); return; } if(WriteTMKFile(SAMID) == SUCC) { WriteLog(DEBUG_LEVEL, "写key文件成功!"); g_pKeyServDlg->SetListCtrl(0, "写key文件成功!"); m_key_info.SetWindowText("写key文件成功!"); } else { WriteLog(DEBUG_LEVEL, "写key文件失败!"); g_pKeyServDlg->SetListCtrl(0, "写key文件失败!"); m_key_info.SetWindowText("写key文件失败!"); m_btn_createkey.EnableWindow(TRUE); return; } WriteLog(DEBUG_LEVEL, "下载主密钥成功!"); g_pKeyServDlg->SetListCtrl(0, "下载主密钥成功!"); m_key_info.SetWindowText("下载主密钥成功!"); int istate = m_chk_auto.GetCheck(); //复选框被选中 if(istate == 1) { long lzSAMID = atol((LPTSTR)(LPCTSTR)pinpadno); lzSAMID++; sprintf(SAMID, "%08ld", lzSAMID); m_pinpadno.UpdateData(FALSE); m_pinpadno.SetWindowText(SAMID); m_pinpadno.UpdateData(TRUE); } m_btn_createkey.EnableWindow(TRUE); }
void connect_uart(void) { int i,j; int ret,len,total_ok=0, total_error=0; int error_count = 1, error_count2 = 2, error_flag = 0; int Ten_thousand = 0; int true_count = 1; unsigned int count = 0; char asc[100]; uint8_t buffer[Recieve_Nbyte]; uint8_t count_buffer[4]; unsigned int get_data = 0; lcd_clrscr(); lcd_disp_string(0, 0, " 直连模式 "); lcd_disp_hline(0, 13, 128); lcd_disp_string(30,16, "蓝牙广播中..."); lcd_disp_string(36,36, "等待连接"); serial_write(CONFIG_BT_SERIAL_NUM, "AT+ADV\r\n", sizeof("AT+ADV\r\n"));//开启广播 serial_read(CONFIG_BT_SERIAL_NUM, buffer, 300, 300); lcd_clrscr(); if (strcmp(buffer, "OK\r\nCONNECTED\r\n") == 0) { lcd_disp_string(26, 26, "蓝牙连接成功"); led_ctrl(1, 1); mdelay(1000); } else { lcd_disp_string(26, 26, "蓝牙连接失败"); led_ctrl(1, 0); mdelay(1000); return 0; } restart: lcd_clrscr(); lcd_disp_string( 14, 0, "数据发送接收测试" ); lcd_disp_hline(0, 13, 128); //lcd_disp_string( 0, 16, "接收发送的数据:" ); lcd_disp_string( 0, 16, "数据接收发送的结果:" ); memset( buffer, 0, sizeof(buffer)); len = 0; while(1) { if ((ret=serial_read(CONFIG_BT_SERIAL_NUM, buffer, Recieve_Nbyte, 200 )) > 0 ){ printf("ret: %d \n", ret); for (i=0; i<Recieve_Nbyte; i++) { printf(" %d ", buffer[i]); } printf("\n"); for (i=0; i<Recieve_Nbyte; i++) { if (buffer[i] == 0x0e) { true_count++; } else { true_count = 1; } if ( true_count == 40) goto out; } lcd_disp_string( 30, 40, " " ); for (i=0; i<(Recieve_Nbyte-4); i++) { if (buffer[i+4] != i) { error_flag = 1; dprintf("\n ----error1:%d ----\n", error_count++); for (j=0; j<Recieve_Nbyte; j++) dprintf(" %d ", buffer[j]); dprintf("\n"); } } memcpy(count_buffer, buffer, 4); bcd2asc(count_buffer, 8, asc, 1); get_data = strtoul(asc,NULL,10); dprintf("\n -get_data %d ", get_data); dprintf("\n -count %d ", count); dprintf("\n ret %d ", ret); if (get_data != count) { error_flag = 1; dprintf("\n error2:%d \n", error_count2++); } count ++; serial_write(CONFIG_BT_SERIAL_NUM, buffer, Recieve_Nbyte); out: if (true_count == 40) { if (error_flag == 0) { lcd_disp_string( 30, 40, "数据收发成功!!!" ); total_ok++; } else { lcd_disp_string( 30, 40, "数据收发失败!!!" ); total_error++; } count = 0; } } if (ret < 0) { lcd_clrscr(); lcd_disp_string(6, 30, "蓝牙等待断开连接..."); serial_write(CONFIG_BT_SERIAL_NUM, "AT+DISC\r\n" , sizeof("AT+DISC\r\n" ));//断开连接 serial_read(CONFIG_BT_SERIAL_NUM, buffer, 300, 300); serial_clrbuf(CONFIG_BT_SERIAL_NUM, 1, 1); lcd_clrscr(); lcd_disp_string(26, 30, "蓝牙已断开连接"); led_ctrl(1, 0); mdelay(1000); return; } #if 0 if((ret=serial_read(CONFIG_BT_SERIAL_NUM, buffer + len, 1, 200 )) > 0 ){ lcd_disp_string( 0, 30, buffer); serial_write(CONFIG_BT_SERIAL_NUM, buffer + len, 1); len ++; } if (ret < 0) { lcd_clrscr(); lcd_disp_string(6, 30, "蓝牙等待断开连接..."); serial_write(CONFIG_BT_SERIAL_NUM, "AT+DISC\r\n" , sizeof("AT+DISC\r\n" ));//断开连接 serial_read(CONFIG_BT_SERIAL_NUM, buffer, 300, 300); serial_clrbuf(CONFIG_BT_SERIAL_NUM, 1, 1); lcd_clrscr(); lcd_disp_string(26, 30, "蓝牙已断开连接"); mdelay(1000); return; } if(len >= 16*3){ goto restart; } // if ( kb_get_key(1000) == KEY_9) { // serial_write(CONFIG_BT_SERIAL_NUM, &send_data, 1); // send_data++; // } #endif } return 0; }
int OnGetRandom(QUEUE_LIST *pDataNode) { thd_log(LOG_DEBUG,(char *)"OnGetRandom...Received Data:"); trace_mem(LOG_DEBUG,(unsigned char *)pDataNode->Buffer,pDataNode->Length); int MSGLength = pDataNode->Length; unsigned char *pMSG = pDataNode->Buffer; // pMSG++; MSGLength--; int iOffset = 0; int DownKeyLen = 0; char DownKey[49] = {0}; char TermNo[17] = {0}; unsigned char TRD[9] = {0}; //加密机产生的随机数据,TTEK加密后送给SPOS服务器 // 输出缓存 char OutBuf[1025] = {0}; char EDownKey[17] = {0}; char chTRD[17] = {0}; unsigned char KeyRandom[8] = {0xD6, 0xA7, 0xB8, 0xB6, 0xCE, 0xDE, 0xD3, 0xC7}; //固定密钥 用来加密终端随机数 char TermNo1[9] = {0}; int iFlag = 0; iOffset += MERNOLENGTH; MSGLength -= MERNOLENGTH; memcpy(TermNo,&pMSG[iOffset],BANKNOLENGTH); // memcpy(TermNo,TermNo,8); //TermNo1 = trim(TermNo); memcpy(TermNo1,TermNo,8); iOffset += BANKNOLENGTH; MSGLength -= BANKNOLENGTH; iFlag = pMSG[iOffset]; //标志位:0:产生随机数;1:密钥下载密码 iOffset += 1; MSGLength -= 1; if(iFlag == 1) { DownKeyLen = pMSG[iOffset]; // 密钥下载密码长度 if(DownKeyLen%8 != 0) { setCmdError2(pDataNode); thd_log(LOG_WARNING,(char *)"OnGetRandom, Data Length is not 8 multiples !"); return 1; } // thd_log(LOG_DEBUG,(char *)"OnGetRandom, Data Length : %d",DownKeyLen); iOffset += 1; MSGLength -= 1; memcpy(DownKey,&pMSG[iOffset],DownKeyLen); //随机数/密钥下载密码 } else if(iFlag == 0) //需要产生随机数 { GetRandom((unsigned char *)DownKey,8); //随机数长度为8 ////测试数据,固定随机数 /* DownKey[0] = 0x88; DownKey[1] = 0x77; DownKey[2] = 0x66; DownKey[3] = 0x55; DownKey[4] = 0x44; DownKey[5] = 0x33; DownKey[6] = 0x22; DownKey[7] = 0x11;*/ ///////////// DownKeyLen = 8; memcpy(TRD,DownKey,8) ; DesEncrypt(1,TRD,TRD,8,KeyRandom); //将随机数用固定密钥加密存放到数据库 bcd2asc(chTRD,(unsigned char *)TRD,8); /*将产生的随机数根据终端号保存到数据库t_bank_key 的random字段*/ SAString sSql; SACommand Cmd; try { Cmd.setConnection(pDataNode->psaConn); sSql.Format("update t_bank_key set random = trim('%s') where termno = trim('%s') ", chTRD,TermNo); Cmd.setCommandText(sSql); Cmd.Execute(); } catch(SAException &x) { thd_log( LOG_ERROR,(char *)"SQLAPI Exception %s", _T(x.ErrText())); thd_log( LOG_ERROR,(char *)"sSQL: %s", _T(sSql)); return false; } } thd_log(LOG_DEBUG,(char *)"OnGetRandom...Random Data:"); trace_mem(LOG_DEBUG,(unsigned char *)DownKey,8); unsigned char TTEK[17] ={0}; if( !CountTTEK(TermNo1, TTEK) ) //用终端号计算TTEK { setCmdError2(pDataNode); return 1; } Des3Encrypt(1,(unsigned char *)EDownKey,(unsigned char *)DownKey,8,TTEK); //用产生的TTEK加密随机数或者下载密钥,返回给服务器 int iOutLen = 0; iOutLen = 2+MERNOLENGTH+POSNOLENGTH+1; setCmdToSeverSucceed(pDataNode,iOutLen,OutBuf); OutBuf[iOutLen] = DownKeyLen; iOutLen += 1; if(DownKeyLen > 1023) { setCmdError2(pDataNode); thd_log(LOG_WARNING,(char *)"OnGetRandom, Track Data Length from HSM is too long!"); return 1; } memcpy(&OutBuf[iOutLen],EDownKey,DownKeyLen); iOutLen += DownKeyLen; memset(pDataNode->Buffer,0,1024); memcpy(pDataNode->Buffer, OutBuf, iOutLen); pDataNode->Length = iOutLen ; thd_log(LOG_DEBUG,(char *)"OnGetRandom, Output Buffer Data:"); trace_mem(LOG_DEBUG,(unsigned char *)pDataNode->Buffer,iOutLen); return 1; }