Mfrc.h
#ifndef _MFRC_H_
#define _MFRC_H_
#include "libreagent.h"
// 应答
#define SW_OK (0x9000)
#define SW_PCD (0x9870)
// 密钥长度
#define KEY_LEN (8)
// 命令长度
#define LENGTH_OF_COMMAND (64)
class REAGENT_EXPORT Mfrc
{
public:
Mfrc();
virtual ~Mfrc();
// 寻试剂卡
virtual quint16 request() = 0;
// 认证(8位密钥)
quint16 authenticate(quint8 keyId, const quint8* key);
// 读写文件
quint16 readBinaryFile(quint8* content, int len, quint8 offset);
quint16 writeBinaryFile(const quint8* content, int len, quint8 offset);
public:
// 取随机数(8字节)
quint16 getChallenge(quint8* challenge);
// 外部认证(8字节随机数)
quint16 externalAuthenticate(quint8 keyId, const quint8* challenge);
// 卡片擦除
quint16 erase();
// 建立目录
quint16 createDfFile(quint16 fileId, quint16 size, quint8 appId);
// 创建密钥文件
quint16 createKeyFile(quint16 fileId, quint16 size);
// 创建二进制文件
quint16 createBinaryFile(quint16 fileId, quint16 size);
// 添加线路保护密钥
quint16 createLineProtectKey(quint8 keyId, const quint8* key);
// 添加外部认证密钥
quint16 createExternalAuthenticateKey(quint8 keyId, const quint8* key);
// 选中文件
quint16 selectMfFile();
quint16 selectFile(quint16 fileId);
protected:
// 格式化
QString toString(const quint8* datas, quint8 len);
// 接收发送
virtual quint16 piccTransceive(quint8* trans, quint8 tlen, quint8* recv, quint8& rlen) = 0;
};
#endif // _MFRC_H_
Mfrc.cpp
#include <QtCore/QtDebug>
#include "des.h"
#include "mfrc.h"
#include "fmcos.h"
#include "utility.h"
Mfrc::Mfrc()
{
}
Mfrc::~Mfrc()
{
}
// 认证(8位密钥)
quint16 Mfrc::authenticate(quint8 keyId, const quint8* key)
{
qDebug() << "Mfrc authenticate" << QString::number(keyId, 16);
// 获取随机数
quint8 challenge[KEY_LEN] = { 0 };
quint16 ret = this->getChallenge(challenge);
if (SW_OK == ret)
{
// 对随机数进行DES加密
quint8 encrypted[KEY_LEN] = { 0 };
Des::encrypt(challenge, key, encrypted, KEY_LEN);
// 外部认证(8字节随机数)
ret = this->externalAuthenticate(keyId, encrypted);
if (SW_OK == ret)
{
}
else
{
qWarning() << "Mfrc authenticate externalAuthenticate fail";
}
}
else
{
qWarning() << "Mfrc authenticate getChallenge fail";
}
return ret;
}
// 读写文件
quint16 Mfrc::readBinaryFile(quint8* content, int len, quint8 offset)
{
qDebug() << "Mfrc readBinaryFile" << QString::number(offset, 16) << QString::number(len, 16);
// 指令
quint8 buf[LENGTH_OF_COMMAND] = { 0 };
quint8 tlen = FMCos::readBinrayCommand(buf, offset, len);
// 发送指令,接收返回值
quint8 rlen = 0;
quint16 ret = this->piccTransceive(buf, tlen, buf, rlen);
if (SW_OK == ret)
{
// 返回随机数(0A 01 84 8A 51 10 9E 2B A7 A2 90 00,跳过0A 01)
memcpy(content, buf + 2, len);
}
return ret;
}
quint16 Mfrc::writeBinaryFile(const quint8* content, int len, quint8 offset)
{
qDebug() << "Mfrc writeBinaryFile" << QString::number(offset, 16) << QString::number(len, 16);
// 指令
quint8 buf[LENGTH_OF_COMMAND] = { 0 };
quint8 tlen = FMCos::writeBinaryCommand(buf, offset, content, len);
// 发送指令,接收返回值
quint8 rlen = 0;
return this->piccTransceive(buf, tlen, buf, rlen);
}
// 取随机数(8字节)
quint16 Mfrc::getChallenge(quint8* challenge)
{
qDebug() << "Mfrc getChallenge";
// 指令
quint8 buf[LENGTH_OF_COMMAND] = { 0 };
quint8 tlen = FMCos::getChallengeCommand(buf, KEY_LEN);
// 发送指令,接收返回值
quint8 rlen = 0;
quint16 ret = this->piccTransceive(buf, tlen, buf, rlen);
if (SW_OK == ret)
{
// 返回随机数(0A 01 84 8A 51 10 9E 2B A7 A2 90 00,跳过0A 01)
memcpy(challenge, buf + 2, KEY_LEN);
}
return ret;
}
// 外部认证(8字节随机数)
quint16 Mfrc::externalAuthenticate(quint8 keyId, const quint8* challenge)
{
qDebug() << "Mfrc externalAuthenticate" << QString::number(keyId, 16);
// 指令
quint8 buf[LENGTH_OF_COMMAND] = { 0 };
quint8 tlen = FMCos::externalAuthenticateCommand(buf, keyId, challenge);
// 发送指令,接收返回值
quint8 rlen = 0;
return this->piccTransceive(buf, tlen, buf, rlen);
}
// 卡片擦除
quint16 Mfrc::erase()
{
qDebug() << "Mfrc erase";
// 指令
quint8 buf[LENGTH_OF_COMMAND] = { 0 };
quint8 tlen = FMCos::eraseCommand(buf);
// 发送指令,接收返回值
quint8 rlen = 0;
return this->piccTransceive(buf, tlen, buf, rlen);
}
// 建立目录
quint16 Mfrc::createDfFile(quint16 fileId, quint16 size, quint8 appId)
{
qDebug() << "Mfrc createDfFile" << QString::number(fileId, 16) << QString::number(size, 16) << QString::number(appId, 16);
// 指令
quint8 buf[LENGTH_OF_COMMAND] = { 0 };
quint8 tlen = FMCos::createDfFileCommand(buf, fileId, size, appId);
// 发送指令,接收返回值
quint8 rlen = 0;
return this->piccTransceive(buf, tlen, buf, rlen);
}