⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cardreviewerdlg.cpp

📁 IC 卡读写操作VC版。有读写功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -