📄 cardreviewerdlg.cpp
字号:
char outData[1024];
if (0 != IC_ReadMifare_Hex(m_hPOS, sector * 4 + block, (BYTE *)outData))
{
return false;
}
memcpy(pData,&outData[0],32);
return true;
}
bool CCardReviewerDlg::ConnectReader(void)
{
if (m_bTrueIsOpen)
{
return true;
}
m_hPOS = IC_InitComm_Baud(100,19200);
if (0 < m_hPOS)
{
m_bTrueIsOpen = true;
}
else
{
return false;
}
IC_DispInfo(m_hPOS, 0, 1, "山东一卡通");
IC_InitType(m_hPOS, 14);
unsigned char relen;
unsigned char redata[64];
IC_CpuReset_Hex(m_hPOS,&relen,redata);
char szAPDU[512] = {0};
char szResp[512] = {0};
memset(szAPDU, 0, sizeof(szAPDU));
memset(szResp, 0, sizeof(szResp));
_snprintf(szAPDU, sizeof(szAPDU), "00A40000023F01");
if(0 >= SendApdu(3, (char *)szAPDU,(char *)szResp))
{
return false;
}
return true;
}
bool CCardReviewerDlg::DisConnectReader(void)
{
IC_ExitComm(m_hPOS);
m_hPOS = 0;
return true;
}
void GetKeyDiv(char *pszCityCode, char (&szGrpNo)[17])
{
char szCityCode[5] = {0};
memcpy(szCityCode, pszCityCode, 4);
int nCityCode = atoi(szCityCode);
memcpy(szGrpNo, "D1CCCCA800000000", 16);
}
// 获取第3 6 快的key
bool CCardReviewerDlg::GetWorkKey(void)
{
int st;
char szAPDU[512] = {0};
char szResp[512] = {0};
char szCardCSN[9] = {0};
char szCityCode[5] = {0};
char szSN[5] = {0};
char szCardMAC[9] = {0};
memset(m_szKey02, 0, sizeof(m_szKey02));
memset(m_szKey03, 0, sizeof(m_szKey03));
memset(m_szKey06, 0, sizeof(m_szKey03));
memcpy(szCardCSN, &m_szCardData[0], 8);
memcpy(szCityCode, &m_szCardData[32 * 4], 4);
memcpy(szCardMAC, &m_szCardData[32 * 4 + 16], 8);
memcpy(szSN, &m_szCardData[32 * 4 + 8 + 4], 4);
char szDivData[17] = {0};
GetKeyDiv(szCityCode, szDivData);
memset(szAPDU, 0, sizeof(szAPDU));
memset(szResp, 0, sizeof(szResp));
_snprintf(szAPDU, sizeof(szAPDU), "80FC0E0D17%s%s%s%s100306%s",
szCityCode, szCardCSN, szSN, szCardMAC, szDivData);
if(0 >= SendApdu(3, (char *)szAPDU,(char *)szResp))
{
return false;
}
memset(szResp, 0, sizeof(szResp));
if(0 >= SendApdu(3, (char *)"00C0000012",(char *)szResp))
{
return false;
}
if(memcmp((const char*)&szResp[36],"9000", 4)!=0)
{
return false;
}
memcpy(m_szKey02, &szResp[0], 12);
memcpy(m_szKey03, &szResp[12], 12);
memcpy(m_szKey06, &szResp[24], 12);
return true;
}
bool CCardReviewerDlg::CardRest(int nSlot, char *pszATR, int nSize)
{
short st;
unsigned long ulSnr=0;
char szBuff[256] = {0};
CString strTmp;
if (0 != IC_Card(m_hPOS,0,&ulSnr))
{
return false;
}
strTmp.Format("%u",ulSnr);
strncpy(szBuff, strTmp.GetBuffer(0), sizeof(szBuff));
if (NULL != pszATR)
{
memcpy(pszATR, szBuff, 8);
}
return true;
}
// read card content
void CCardReviewerDlg::ReadCardContent(void)
{
char szATR[64] = {0};
char szInfo[256] = {0};
char szKey[16] = {0};
memset(m_szCardData, 0, sizeof(m_szCardData));
m_ListAnalyse.ClearStr();
ConnectReader();
int nBlckNo = 0;
int nCur = 0;
//认证0扇区 应用标识目录区
if (!LoadKey((unsigned char*)"A0A1A2A3A4A5", 0))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "0扇区加载密钥失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
if (!Authentic(0,0))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "0扇区密钥认证失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
// 读取0扇区内容
for (nCur = 0; nCur < 3; nCur++)
{
if (!ReadBlock(0, nCur, (unsigned char*)&m_szCardData[32 * nBlckNo]))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "读取S0B%d失败", nCur);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
nBlckNo++;
}
nBlckNo++;
memcpy(&szKey[0], &m_szCardData[0], 8);
memcpy(&szKey[8], &m_szCardData[0], 4);
//认证1扇区 应用标识目录区
if (!LoadKey((unsigned char*)szKey, 1))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "1扇区加载密钥失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
if (!Authentic(1,0))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "1扇区密钥认证失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
// 读取1扇区内容
for (nCur = 0; nCur < 3; nCur++)
{
if (!ReadBlock(1, nCur, (unsigned char*)&m_szCardData[32 * nBlckNo]))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "读取S1B%d失败", nCur);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
nBlckNo++;
}
nBlckNo++;
if (!GetWorkKey())
{
MessageBox("获取工作密钥失败!");
return ;
}
//认证2扇区 应用标识目录区
if (!LoadKey((unsigned char*)m_szKey02, 2))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "2扇区加载密钥失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
if (!Authentic(2,1))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "2扇区密钥认证失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
// 读取2扇区内容
for (nCur = 0; nCur < 3; nCur++)
{
if (!ReadBlock(2, nCur, (unsigned char*)&m_szCardData[32 * nBlckNo]))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "读取S2B%d失败", nCur);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
nBlckNo++;
}
nBlckNo++;
// 读取交易记录区信息
for (int nBn = 0; nBn < 3; nBn++)
{
if (!LoadKey((unsigned char*)m_szKey03, 3 + nBn))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "%d扇区加载密钥失败", 3 + nBn);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
if (!Authentic(3 + nBn, 1))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "%d扇区密钥认证失败", 3 + nBn);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
for (nCur = 0; nCur < 3; nCur++)
{
if (!ReadBlock(3 + nBn, nCur, (unsigned char*)&m_szCardData[32 * nBlckNo]))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "读取S%dB%d失败", 3 + nBn, nCur);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
nBlckNo++;
}
nBlckNo++;
}
//认证6扇区
if (!LoadKey((unsigned char*)m_szKey06, 6))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "6扇区加载密钥失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
if (!Authentic(6,1))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "6扇区密钥认证失败");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
// 读取6扇区内容
for (nCur = 0; nCur < 3; nCur++)
{
if (!ReadBlock(6, nCur, (unsigned char*)&m_szCardData[32 * nBlckNo]))
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "读取S2B%d失败", nCur);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
nBlckNo++;
}
}
void CCardReviewerDlg::SetEditText(int nID, char *pszValue)
{
CEdit *pEdit = (CEdit *)this->GetDlgItem(nID);
if (NULL != pEdit)
{
pEdit->SetWindowText(pszValue);
}
}
//检查公共扇区是否合法
bool CCardReviewerDlg::IsValidPublic(char* pData)
{
bool bRes = true;
if (NULL == pData || '\0' == pData[0])
{
bRes = false;
}
char szInfo[256] = {0};
memset(szInfo, 0, sizeof(szInfo));
char tmp=HexStrToLong(&pData[0],2);
if(tmp<1||tmp>9)
{
_snprintf(szInfo, sizeof(szInfo), "交易指针不合法");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
bRes = false;
}
tmp=HexStrToLong(&pData[6],2);
if(tmp<1||tmp>8)
{
_snprintf(szInfo, sizeof(szInfo), "交易进程标志不合法");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
bRes = false;
}
BYTE result[9];
memset(result,0x00,sizeof(result));
StrXor((char*)&pData[0], 30,(char*)result);
if(memcmp(&pData[30],result,2)!=0)
{
bRes = false;
}
return bRes;
}
//检查钱包是否合法
bool CCardReviewerDlg::IsValidPurse(char* pData)
{
bool bRes = true;
char szInfo[256] = {0};
memset(szInfo, 0, sizeof(szInfo));
if (NULL == pData || '\0' == pData[0])
{
bRes = false;
}
if(memcmp(&pData[0],&pData[16],8)!=0)
{
_snprintf(szInfo, sizeof(szInfo), "钱包数据不一致");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
bRes = false;
}
//钱包取反
char tmp[9];
memset(tmp,0x00,sizeof(tmp));
StrNot((BYTE*)pData,8,(BYTE*)tmp);
if(memcmp(&pData[8],tmp,8)!=0)
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "钱包反值不对");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
bRes = false;
}
if(memcmp(&pData[24],&pData[28],4)!=0)
{
memset(szInfo, 0, sizeof(szInfo));
_snprintf(szInfo, sizeof(szInfo), "钱包校验错误");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
bRes = false;
}
// if(HexStrToLong(&pData[24],2)
// +HexStrToLong(&pData[26],2)!=0xFF)
// {
// memset(szInfo, 0, sizeof(szInfo));/
// _snprintf(szInfo, sizeof(szInfo), "钱包校验码错误");
// m_ListAnalyse.AddMsg(szInfo, M_ERROR);
// /bRes = false;
// }
return bRes;
}
// analanyse card
void CCardReviewerDlg::AnalanyCard(void)
{
char szVerifyVal[3] = {0};
char szInfo[256] = {0};
char *pszPos = NULL;
int nCur = 0;
if ('\0' == m_szCardData[0])
{
_snprintf(szInfo, sizeof(szInfo), "读卡错误");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
return ;
}
// 应用标识目录区
memset(szVerifyVal, 0, sizeof(szVerifyVal));
memset(szInfo, 0, sizeof(szInfo));
StrXor((char *)&m_szCardData[2 * 32], 30, (char *)szVerifyVal);
if (memcmp(&m_szCardData[2 * 32 + 30], szVerifyVal, 2) != 0)
{
_snprintf(szInfo, sizeof(szInfo), "S0B2校验位错误");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
else
{
_snprintf(szInfo, sizeof(szInfo), "S0B2校验位正确");
m_ListAnalyse.AddMsg(szInfo, M_OK);
}
// 发行区
for (nCur = 0; nCur < 3; nCur++)
{
memset(szVerifyVal, 0, sizeof(szVerifyVal));
memset(szInfo, 0, sizeof(szInfo));
pszPos = &m_szCardData[(4 + nCur) * 32];
StrXor((char *)pszPos, 30, (char *)szVerifyVal);
if (memcmp(pszPos + 30, szVerifyVal, 2) != 0)
{
_snprintf(szInfo, sizeof(szInfo), "S1B%d校验位错误", nCur);
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
else
{
_snprintf(szInfo, sizeof(szInfo), "S1B%d校验位正确", nCur);
m_ListAnalyse.AddMsg(szInfo, M_OK);
}
}
// 公用钱包区
memset(szVerifyVal, 0, sizeof(szVerifyVal));
memset(szInfo, 0, sizeof(szInfo));
StrXor((char *)&m_szCardData[8 * 32], 30, (char *)szVerifyVal);
if (memcmp(&m_szCardData[8 * 32 + 30], szVerifyVal, 2) != 0)
{
_snprintf(szInfo, sizeof(szInfo), "S2B0校验位错误");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
else
{
_snprintf(szInfo, sizeof(szInfo), "S2B0校验位正确");
m_ListAnalyse.AddMsg(szInfo, M_OK);
}
memset(szInfo, 0, sizeof(szInfo));
if (memcmp(&m_szCardData[9 * 32], &m_szCardData[10 * 32], 32) != 0)
{
_snprintf(szInfo, sizeof(szInfo), "钱包和备用钱包不符!");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
else
{
_snprintf(szInfo, sizeof(szInfo), "钱包和备用钱包符合");
m_ListAnalyse.AddMsg(szInfo, M_OK);
}
memset(szInfo, 0, sizeof(szInfo));
if (!IsValidPurse(&m_szCardData[9 * 32]))
{
_snprintf(szInfo, sizeof(szInfo), "钱包数据不合法,应做修复!");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
else
{
_snprintf(szInfo, sizeof(szInfo), "钱包数据合法");
m_ListAnalyse.AddMsg(szInfo, M_OK);
}
memset(szInfo, 0, sizeof(szInfo));
if (!IsValidPurse(&m_szCardData[10 * 32]))
{
_snprintf(szInfo, sizeof(szInfo), "备用钱包数据不合法,应做修复!");
m_ListAnalyse.AddMsg(szInfo, M_ERROR);
}
else
{
_snprintf(szInfo, sizeof(szInfo), "备用钱包数据合法");
m_ListAnalyse.AddMsg(szInfo, M_OK);
}
// 公用信息区
for (nCur = 0; nCur < 2; nCur++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -