本示例使用的发卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bYhsS9c&ft=t&id=917152255720
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices; //调用动态库一定要加入这个引用
namespace MifareDesfireEv123
{
public partial class Form1 : Form
{
//外部函数声明:让设备发出声响--------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdbeep", CallingConvention = CallingConvention.StdCall)]
static extern byte pcdbeep(Int32 xms);//xms单位为毫秒
//读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限-----------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdgetdevicenumber", CallingConvention = CallingConvention.StdCall)]
static extern byte pcdgetdevicenumber(byte[] devicenumber);//devicenumber用于返回编号
//获取IC卡芯片型号----------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "getmifareversion")]
static extern byte getmifareversion(byte[] cardtypestr, byte[] AtqaSak, byte[] versionbuf, byte[] versionlen, byte[] retsw);
//激活Desfire卡、CPU卡------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "cpurequest1")]
static extern byte cpurequest1(byte[] mypiccserial, byte[] myparam, byte[] myver, byte[] mycode, byte[] AtqaSak);
//选择desfire卡 应用ID------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfireselectapplication")]
static extern byte desfireselectapplication(byte[] aid, byte[] retsw);
//EV1密钥认证---------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfireauthkeyev1")]
static extern byte desfireauthkeyev1(byte[] keybuf, byte keyid,byte authmode,byte[] retsw);
//EV1更改密钥---------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfirechangekeyev1")]
static extern byte desfirechangekeyev1(byte[] newkeybuf, byte keyid, byte authmode, byte zeno, byte[] oldkeybuf, byte[] retsw);
//EV2密钥认证---------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfireauthkeyev2")]
static extern byte desfireauthkeyev2(byte[] keybuf, byte keyid, byte authmode, byte[] retsw);
//初始化卡(格式化卡) 返回 910E 时用-----------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfireformatpicc")]
static extern byte desfireformatpicc(byte[] retsw);
//删除desfire卡内的应用AID------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfiredeleteapplication")]
static extern byte desfiredeleteapplication(byte[] aid, byte[] retsw);
//在desfire卡根目录下创建新应用AID-----------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfirecreateapplication")]
static extern byte desfirecreateapplication(byte[] aid, byte keysetting,byte keynumver, byte keytype, byte[] retsw);
//查询desfire卡内所有的应用AID-----------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfiregetapplicationids")]
static extern byte desfiregetapplicationids(byte[] aidbuf, byte[] aidsize, byte[] retsw);
//获取AID应用的密钥配置信息-----------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfiregetkeysettings")]
static extern byte desfiregetkeysettings(byte[] aidbuf, byte[] keysetting, byte[] keysize, byte[] retsw);
//更改desfire卡内的应用的密钥配置信息-----------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfirechangekeysettings")]
static extern byte desfirechangekeysettings(byte[] aidbuf, byte keysetting, byte[] retsw);
//在desfire应用中创建标准文件------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfirecreatestddatafile")]
static extern byte desfirecreatestddatafile(byte fileid, byte comset, byte[] accessrights, Int32 filesize, byte[] retsw);
//在desfire应用中创建备份文件------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfircreatebackupdatafile")]
static extern byte desfircreatebackupdatafile(byte fileid, byte comset, byte[] accessrights, Int32 filesize, byte[] retsw);
//读取应用中的所有文件ID------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfiregetfileids")]
static extern byte desfiregetfileids(byte[] fileid, byte[] filessize, byte[] retsw);
//读取desfire卡应用中文件的配置信息------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfiregetfilesettings")]
static extern byte desfiregetfilesettings(byte fileid, byte[] filesettingsbuf, byte[] revbuflen, byte[] retsw);
//更改desfire卡应用中文件的配置信息------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfirechangefilesettings")]
static extern byte desfirechangefilesettings(byte fileid, byte comset, byte[] accessrights, byte[] retsw);
//删除应用中的文件-----------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfiredeletefile")]
static extern byte desfiredeletefile(byte fileid, byte[] retsw);
//读文件-----------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfirereaddata")]
static extern byte desfirereaddata(byte cmd, byte fileno, Int32 offset, Int32 datalen, byte[] databuf, byte[] retsw);
//写文件-----------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfirewritedata")]
static extern byte desfirewritedata(byte cmd, byte fileno, Int32 offset, Int32 datalen, byte[] databuf, byte[] retsw);
public Form1()
{
InitializeComponent();
}
//函数返回状态解析
private static byte MessageDispInfo(byte errno)
{
switch (errno)
{
case 0:
MessageBox.Show("操作成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
case 8:
MessageBox.Show("请重新拿开卡后再放到感应区!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 23:
MessageBox.Show("错误代码:" + errno.ToString("D") + ",驱动程序错误或尚未安装!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 24:
MessageBox.Show("错误代码:" + errno.ToString("D") + ",操作超时,一般是动态库没有反映!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 25:
MessageBox.Show("错误代码:" + errno.ToString("D") + ",发送字数不够!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 26:
MessageBox.Show("错误代码:" + errno.ToString("D") + ",发送的CRC错!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 27:
MessageBox.Show("错误代码:" + errno.ToString("D") + ",接收的字数不够!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 28:
MessageBox.Show("错误代码:" + errno.ToString("D") + ",接收的CRC错!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 50:
MessageBox.Show("RATS错误,厂家调试代码,用户不需理会!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 51:
MessageBox.Show("PPS错误,厂家调试代码,用户不需理会!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 52:
MessageBox.Show("已进入了14443-4协议状态,可进行CPU卡功能所有操作了!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 53:
MessageBox.Show("CPU卡功能通讯错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 54:
MessageBox.Show("数据不足,需要接着发送未完成的数据至卡上!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 55:
MessageBox.Show("发送ACK指令给卡,让卡接着发送数据回来!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 56:
MessageBox.Show("清空根目录失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 57:
MessageBox.Show("卡片不支持功能!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 58:
MessageBox.Show("卡片初始化失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 59:
MessageBox.Show("分配的空间不足!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 60:
MessageBox.Show("本次操作的实体已存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 61:
MessageBox.Show("无足够空间!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 62:
MessageBox.Show("文件不存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 63:
MessageBox.Show("权限不足,有可能是用只读密码认证,导致无法更改读写密码或无法写文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 64:
MessageBox.Show("密码不存在,或密钥文件未创建!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 65:
MessageBox.Show("传送长度错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 66:
MessageBox.Show("Le错误,即接收的数据长度指定过大!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 67:
MessageBox.Show("功能不支持或卡中无MF 或卡片已锁定!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 68:
MessageBox.Show("密码认证错识次数过多,该密码已被锁死!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 86:
MessageBox.Show("更改后的密码长度必须和创建时的长度一致!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 87:
MessageBox.Show("应用目录不存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 88:
MessageBox.Show("应用文件不存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 89:
MessageBox.Show("文件号不能超过5!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 90:
MessageBox.Show("读取文件时返回的长度不足,数据可能不正确!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 91:
MessageBox.Show("一次读文件的长度不能超过255!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 92:
MessageBox.Show("一次写文件的长度不能超过247!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 70:
case 71:
case 72:
case 73:
case 74:
case 75:
case 76:
case 77:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
MessageBox.Show("密码错误,剩余次数为" + Convert.ToString(errno - 70) + ",如果为0,该密码将锁死,无法再认证", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
default:
MessageBox.Show("操作失败,返回错误代码!" + Convert.ToString(errno), "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
}
return 0;
}
//判断16进制数据是否正确
public static bool checkhexstr(string inputstr,int hexlen,byte[] bytebuf )
{
try
{
inputstr = inputstr.Replace(" ", "");
inputstr = inputstr.Replace("\r", "");
inputstr = inputstr.Replace("\n", "");
for (int i=0;i<hexlen;i++){
bytebuf[i] = Convert.ToByte(Convert.ToInt32(inputstr.Substring(i * 2, 2), 16));
}
return true;
}
catch{
return false;
}
}
//卡操作返回代码解析
public static string RetTextFromStr(string inputstr)
{
string RetTextFromStr = "";
switch (inputstr)
{
case "9000":
RetTextFromStr = "成功!";
break;
case "9100":
RetTextFromStr = "成功!";
pcdbeep(20);
break;
case "6281":
RetTextFromStr = "回送的数据可能错误!";
break;
case "6283":
RetTextFromStr = "选择文件无效,文件或密钥校验错误";
break;
case "6400":
RetTextFromStr = "状态标志未改变";
break;
case "6581":
RetTextFromStr = "写 EEPROM 不成功!";
break;
case "6700":
RetTextFromStr = "长度错误";
break;
case "6900":
RetTextFromStr = "CLA 与线路保护要求不匹配";
break;
case "6901":
RetTextFromStr = "无效的状态!";
break;
case "6981":
RetTextFromStr = "命令与文件结构不相容";
break;
case "6982":
RetTextFromStr = "不满足安全状态";
break;
case "6983":
RetTextFromStr = "密钥被锁死!";
break;
case "6984":
RetTextFromStr = "MAC格式不符合";
break;
case "6985":
RetTextFromStr = "使用条件不满足";
break;
case "6986":
RetTextFromStr = "请先选择文件!";
break;
case "6987":
RetTextFromStr = "无安全报文";
break;
case "6988":
RetTextFromStr = "安全报文数据项不正确";
break;
case "6A80":
RetTextFromStr = "数据域参数错误!";
break;
case "6A81":
RetTextFromStr = "功能不支持或卡中无MF 或卡片已锁定";
break;
case "6A82":
RetTextFromStr = "文件未找到";
break;
case "6A83":
RetTextFromStr = "记录未找到!";
break;
case "6A84":
RetTextFromStr = "文件无足够空间";
break;
case "6A86":
RetTextFromStr = "参数P1 P2 错";
break;
case "6A88":
RetTextFromStr = "密钥未找到!";
break;
case "6B00":
RetTextFromStr = "在达到Le/Lc 字节之前文件结束,偏移量错误";
break;
case "6E00":
RetTextFromStr = "无效的CLA";
break;
case "6F00":
RetTextFromStr = "数据无效!";
break;
case "9302":
RetTextFromStr = "MAC 错误";
break;
case "9303":
RetTextFromStr = "应用已被锁定";
break;
case "9401":
RetTextFromStr = "金额不足!";
break;
case "9403":
RetTextFromStr = "密钥未找到!";
break;
case "9406":
RetTextFromStr = "所需的MAC 不可用!";
break;
case "91AE":
RetTextFromStr = "认证失败,请检查命行的参数和前期计算是否错误!";
break;
case "91CA":
RetTextFromStr = "上一个命令未完全完成!";
break;
case "917E":
RetTextFromStr = "指令长度错误!";
break;
case "9140":
RetTextFromStr = "当前目录或应用密钥不存在,请先选择正确的目录或应用!";
break;
case "919D":
RetTextFromStr = "处于未验证密码的状态,该指令无法操作!";
break;
case "911E":
RetTextFromStr = "MAC错误!";
break;
case "91F0":
RetTextFromStr = "该文件号不存在!";
break;
case "919E":
RetTextFromStr = "参数无效!";
break;
case "91BE":
RetTextFromStr = "试图读取/写入的数据超出文件/记录的边界!";
break;
case "91A0":
RetTextFromStr = "请求的 AID 不存在!";
break;
default:
if (inputstr.Substring(0, 3) == "63C")
{
int i = Convert.ToInt16(inputstr.Substring(3, 1), 16);
if(i>0){
RetTextFromStr = "再试 "+i.ToString("D")+" 次错误密码将锁定!";
}
else { RetTextFromStr = "密码已被锁定"; }
}
else{
RetTextFromStr="未知的异常";
}
break;
}
return RetTextFromStr;
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.SelectedIndex = 0;
comboBox3.SelectedIndex = 0;
comboBox14.SelectedIndex = 0;
comboBox2.SelectedIndex = 0;
comboBox4.SelectedIndex = 0;
comboBox5.SelectedIndex = 1;
comboBox6.SelectedIndex = 1;
comboBox7.SelectedIndex = 1;
comboBox8.SelectedIndex = 1;
comboBox9.SelectedIndex = 0;
comboBox10.SelectedIndex = 14;
comboBox11.SelectedIndex = 14;
comboBox12.SelectedIndex = 14;
comboBox13.SelectedIndex = 14;
}
private void button1_Click(object sender, EventArgs e)
{
byte status; //'存放返回值
byte[] mypiccserial = new byte[7];//'卡序列号
byte[] myparam = new byte[4];
byte[] AtqaSak = new byte[3];
byte[] myver = new byte[1];
byte[] mycode = new byte[1];
string cardhohex = "";
string parastr = "";
string verstr = "";
string codestr = "";
int i;
status = cpurequest1(mypiccserial, myparam, myver, mycode, AtqaSak);
if (status == 0 || status == 52)
{
pcdbeep(20);
if (AtqaSak[0] / 64 > 0)
{
for (i = 0; i < 7; i++) { cardhohex = cardhohex + mypiccserial[i].ToString("X2"); }
for (i = 0; i < 4; i++) { parastr = parastr + myparam[i].ToString("X2"); }
verstr = myver[0].ToString("X2");
codestr = mycode[0].ToString("X2");
textBox1.Text = cardhohex;
MessageBox.Show("激活Desfire卡成功,可以接着重复操作第二步进行调试了。\r\n" + "16进制卡号:" + cardhohex + "\r\n参数:" + parastr + "\r\n版本信息:" + verstr + "\r\n厂商代码(复旦为90):" + codestr, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
for (i = 0; i < 4; i++) { cardhohex = cardhohex + mypiccserial[i].ToString("X2"); }
for (i = 0; i < 4; i++) { parastr = parastr + myparam[i].ToString("X2"); }
verstr = myver[0].ToString("X2");
codestr = mycode[0].ToString("X2");
textBox1.Text = cardhohex;
MessageBox.Show("激活Fm1208CPU卡成功,可以接着重复操作第二步进行调试了。\r\n" + "16进制卡号:" + cardhohex + "\r\n参数:" + parastr + "\r\n版本信息:" + verstr + "\r\n厂商代码(复旦为90):" + codestr, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
{
MessageDispInfo(status);
}
}
private void button2_Click(object sender, EventArgs e)
{
byte[] aidbuf =new byte[3];
byte[] retsw = new byte[2];
string retstr;
if (checkhexstr(textBox2.Text.Trim(),3 ,aidbuf)==false) {
MessageBox.Show("十六进制AID输入错误,请输入3字节的16进制AID!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte status = desfireselectapplication(aidbuf, retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("选择卡内应用AID操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("选择卡内应用AID操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button4_Click(object sender, EventArgs e)
{
byte status = pcdbeep(50);
if (status != 0)
{
MessageDispInfo(status);
}
}
private void button8_Click(object sender, EventArgs e)
{
byte[] devno = new byte[4];
byte status = pcdgetdevicenumber(devno);
if (status == 0)
{
pcdbeep(50);
MessageBox.Show("设备的序列号为:" + devno[0].ToString("D3") + "-" + devno[1].ToString("D3") + "-" + devno[2].ToString("D3") + "-" + devno[3].ToString("D3"), "示例程序", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else { MessageDispInfo(status); }
}
private void button3_Click(object sender, EventArgs e)
{
byte[] authkeybuf = new byte[24];
byte[] retsw = new byte[2];
string retstr;
int keylen;
switch (comboBox1.SelectedIndex)
{
case 0:
keylen=8;
break;
case 1:
keylen = 16;
break;
case 2:
keylen = 24;
break;
default :
keylen = 16;
break;
}
if (checkhexstr(textBox3.Text.Trim(), keylen, authkeybuf) == false)
{
MessageBox.Show("十六进制认证密钥输入错误,请输入 "+keylen.ToString("D")+ " 字节的16进制认证密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte status = desfireauthkeyev1(authkeybuf, Convert.ToByte(keyid.Value), Convert.ToByte(comboBox1.SelectedIndex), retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("认证密码操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("认证密码操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBox1.SelectedIndex)
{
case 0:
textBox3.Text = "00 00 00 00 00 00 00 00";
break;
case 1:
textBox3.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
break;
case 2:
textBox3.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
break;
default :
textBox3.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
break;
}
}
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBox3.SelectedIndex)
{
case 0:
textBox3.Text = "00 00 00 00 00 00 00 00";
textBox4.Text = "00 00 00 00 00 00 00 00";
break;
case 1:
textBox3.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
textBox4.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
break;
case 2:
textBox3.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
textBox4.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
break;
default :
textBox3.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
textBox4.Text = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
break;
}
}
private void button6_Click(object sender, EventArgs e)
{
byte[] newkeybuf = new byte[24];
byte[] oldkeybuf = new byte[24];
byte[] retsw = new byte[2];
string retstr;
int keylen;
switch (comboBox3.SelectedIndex)
{
case 0:
keylen = 8;
break;
case 1:
keylen = 16;
break;
case 2:
keylen = 24;
break;
default:
keylen = 16;
break;
}
if (checkhexstr(textBox4.Text.Trim(), keylen, newkeybuf) == false)
{
MessageBox.Show("十六进制新密钥输入错误,请输入 " + keylen.ToString("D") + " 字节的16进制新密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (checkhexstr(textBox3.Text.Trim(), keylen, oldkeybuf) == false)
{
MessageBox.Show("十六进制旧密钥输入错误,请输入 " + keylen.ToString("D") + " 字节的16进制旧密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte status = desfirechangekeyev1(newkeybuf, Convert.ToByte(keyid.Value), Convert.ToByte(comboBox3.SelectedIndex),0,oldkeybuf, retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("EV1更改密码操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("EV1更改密码操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button5_Click(object sender, EventArgs e)
{
byte[] retsw = new byte[2];
string retstr;
byte status = desfireformatpicc(retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("初始格式化卡操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("初始格式化卡操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button7_Click(object sender, EventArgs e)
{
byte[] AtqaSak = new byte[3];
byte[] retsw = new byte[2];
byte[] versionbuf = new byte[100];
byte[] versionlen = new byte[2];
byte[] cardtypebuf = new byte[1024];
byte status = getmifareversion(cardtypebuf, AtqaSak, versionbuf, versionlen, retsw);
string cardtypestr = Encoding.ASCII.GetString(cardtypebuf).Trim() ;
string retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageDispInfo(status);
}
else
{
MessageBox.Show("获取IC卡芯片型号操作,卡片返回代码:" + retstr + "\r\n型号:" + cardtypestr, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button10_Click(object sender, EventArgs e)
{
byte[] aidbuf = new byte[3];
byte[] retsw = new byte[2];
string retstr;
if (checkhexstr(textBox5.Text.Trim(), 3, aidbuf) == false)
{
MessageBox.Show("十六进制AID输入错误,请输入3字节的16进制AID!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte status = desfiredeleteapplication(aidbuf, retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("删除卡内应用操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("删除卡内应用操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button9_Click(object sender, EventArgs e)
{
byte[] aidbuf = new byte[3];
byte[] retsw = new byte[2];
string retstr;
if (checkhexstr(textBox5.Text.Trim(), 3, aidbuf) == false)
{
MessageBox.Show("十六进制AID输入错误,请输入3字节的16进制AID!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte keysetting =Convert.ToByte ( comboBox4.SelectedIndex * 16+comboBox5.SelectedIndex * 8+comboBox6.SelectedIndex * 4+comboBox7.SelectedIndex * 2+comboBox8.SelectedIndex );
byte status = desfirecreateapplication(aidbuf, keysetting,Convert.ToByte(keynumber.Value),Convert.ToByte(comboBox2.SelectedIndex), retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("创建新应用操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("创建新应用操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button11_Click(object sender, EventArgs e)
{
byte status; //函数返回值
byte comset; //通讯模式
byte[] accessrights = new byte[2]; //文件访问时的密钥认证方式
byte[] retsw = new byte[2]; //卡片返回值
string retstr;
Int32 filebytes = Convert.ToInt32(filesize.Value);
if (comboBox9.SelectedIndex < 2)
{
comset =Convert.ToByte (comboBox9.SelectedIndex);
}
else { comset = 3; }
accessrights[1] =Convert.ToByte(comboBox10.SelectedIndex * 16 + comboBox11.SelectedIndex);
accessrights[0] = Convert.ToByte(comboBox12.SelectedIndex * 16 + comboBox13.SelectedIndex);
if (radioButton1.Checked)
{
status = desfirecreatestddatafile(Convert.ToByte(fileid.Value), comset, accessrights, filebytes, retsw);
}
else
{
status = desfircreatebackupdatafile(Convert.ToByte(fileid.Value), comset, accessrights, filebytes, retsw);
}
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status == 53)
{
MessageBox.Show("在应用内创建新文件操作返回异常:" + status.ToString("D") + ",说明:CPU卡功能通讯错误,可能是卡拿开重放后未激活或卡不在感应区!" , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
if (status == 64)
{
if (retstr == "91DE")
{
MessageBox.Show("在应用内创建新文件操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",可能的原因:1 应用没选择对,2 密码未认证,3 文件已存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
MessageBox.Show("在应用内创建新文件操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",请选择正确的应用!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else
{
if (status > 0)
{
MessageBox.Show("在应用内创建新文件操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:"+RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
MessageBox.Show("在应用内创建新文件操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void button12_Click(object sender, EventArgs e)
{
byte[] revbuflen=new byte[4];
byte[] filesettingsbuf=new byte[32];
byte[] retsw = new byte[2]; //卡片返回值
string retstr;
string revstr = "";
byte status = desfiregetfilesettings(Convert.ToByte(fileid.Value), filesettingsbuf, revbuflen, retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("读取文件配置信息返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Int32 revlen = BitConverter.ToInt32(revbuflen, 0);
for (Int32 j = 0; j < revlen;j++ )
{
revstr = revstr + filesettingsbuf[j].ToString("X2");
}
if (filesettingsbuf[1] % 4 == 3) { //解析通信模式
comboBox9.SelectedIndex = 2;
} else{
if (filesettingsbuf[1] % 4 == 1){
comboBox9.SelectedIndex = 1;
}else{
comboBox9.SelectedIndex = 0;
}
}
comboBox10.SelectedIndex = filesettingsbuf[3] / 16; //只读时需要的密码号
comboBox11.SelectedIndex = filesettingsbuf[3] % 16; //只写时需要的密码号
comboBox12.SelectedIndex = filesettingsbuf[2] / 16; //读写时需要的密码号
comboBox13.SelectedIndex = filesettingsbuf[2] % 16; //更改本配置时需要的密码号
filesize.Value = filesettingsbuf[4] + filesettingsbuf[5] * 256 + filesettingsbuf[6] * 65536;
MessageBox.Show("读取文件配置返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr) + ",16进制文件配置信息:" + revstr, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void button14_Click(object sender, EventArgs e)
{
byte[] retsw = new byte[2]; //卡片返回值
string retstr;
byte status = desfiredeletefile(Convert.ToByte(fileid.Value), retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("删除文件操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("删除文件操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr) , "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button15_Click(object sender, EventArgs e)
{
byte cmd = 0xBD; //函数第1个参数为&HBD表示读数据,为&hBB表示读记录
byte[] databuf = new byte[8192];
byte[] retsw = new byte[2]; //卡片返回值
string retstr;
byte status = desfirereaddata(cmd, Convert.ToByte(fileid.Value), Convert.ToInt32(rwbegin.Value), Convert.ToInt32(rwlen.Value), databuf, retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status == 63)
{
MessageBox.Show("读文件操作返回异常:" + status.ToString("D") + ",说明:权限不足,请先用正确的密钥号认证!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
if (status > 0)
{
MessageBox.Show("读文件操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
string datastr = "";
for (Int32 j = 0; j < Convert.ToInt32(rwlen.Value); j++)
{
datastr = datastr + databuf[j].ToString("X2") + " ";
}
textBox8.Text = datastr;
MessageBox.Show("读文件操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
private void button17_Click(object sender, EventArgs e)
{
Int32 i = 0;
string datastr = "";
for (Int32 j = 0; j < Convert.ToInt32(rwlen.Value); j++)
{
datastr = datastr + i.ToString("X2") + " ";
i++;
if (i == 256) { i = 0; }
}
textBox8.Text = datastr;
}
private void button16_Click(object sender, EventArgs e)
{
byte cmd = 0x3D; //函数第1个参数为&H3D表示写数据,为&h3B表示写记录
byte[] databuf = new byte[8192];
byte[] retsw = new byte[2]; //卡片返回值
string retstr;
if (checkhexstr(textBox8.Text.Trim(), Convert.ToInt32(rwlen.Value), databuf) == false)
{
if (MessageBox.Show("写入数据输入不足或错误,是否要生成写入数据?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes )
{
button17.PerformClick();
}
return;
}
byte status = desfirewritedata(cmd, Convert.ToByte(fileid.Value), Convert.ToInt32(rwbegin.Value), Convert.ToInt32(rwlen.Value), databuf, retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status == 63)
{
MessageBox.Show("写文件操作返回异常:" + status.ToString("D") + ",说明:权限不足,请先用正确的密钥号认证!" , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
if (status > 0)
{
MessageBox.Show("写文件操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
MessageBox.Show("写文件操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
private void button18_Click(object sender, EventArgs e)
{
byte[] authkeybuf = new byte[24];
byte[] retsw = new byte[2];
string retstr;
int keylen=16;
if (checkhexstr(textBox6.Text.Trim(), keylen, authkeybuf) == false)
{
MessageBox.Show("十六进制认证密钥输入错误,请输入 " + keylen.ToString("D") + " 字节的16进制认证密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte status = desfireauthkeyev2(authkeybuf, Convert.ToByte(keyid.Value), Convert.ToByte(comboBox14.SelectedIndex), retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("认证密码操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("认证密码操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void Button20_Click(object sender, EventArgs e)
{
byte[] retsw = new byte[2];
byte[] aidsize = new byte[1]; //返回的应用数量,最大19个
byte[] aidbuf = new byte[57]; //应用AID号数据缓冲,每个AID号占用3个字节,最多19个应AID号
byte status = desfiregetapplicationids(aidbuf, aidsize, retsw);
string retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("搜索当前卡片内所有应用AID操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string strls1="";
if (aidsize[0] > 0)
{
strls1 = "应用AID:" + aidbuf[0].ToString("X2") + aidbuf[1].ToString("X2")+ aidbuf[2].ToString("X2");
byte j=1;
while (j<aidsize[0]){
strls1 = strls1 + "," + aidbuf[j * 3].ToString("X2") + aidbuf[j * 3 + 1].ToString("X2") + aidbuf[j * 3 + 2].ToString("X2");
j++;
}
}
MessageBox.Show("搜索当前卡片内所有应用AID操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr) + "\r\n应用数量:" + aidsize[0].ToString("D") +"\r\n" + strls1, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void Button21_Click(object sender, EventArgs e)
{
byte[] aidbuf = new byte[3];
byte[] keysetting = new byte[1];
byte[] keysize = new byte[1];
byte[] retsw = new byte[2];
if (checkhexstr(textBox5.Text.Trim(), 3, aidbuf) == false)
{
MessageBox.Show("十六进制AID输入错误,请输入3字节的16进制AID!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte status = desfiregetkeysettings(aidbuf, keysetting, keysize, retsw);
string retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status == 94)
{
MessageBox.Show("请先执行选择应用AID:" + textBox5.Text.Trim(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
if (status > 0)
{
MessageBox.Show("读取应用的配置信息操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
comboBox4.SelectedIndex = keysetting[0] / 16; //更改应用密钥(非应用主密钥) 需要验证的选项
if ((keysetting[0] & 8)>0){
comboBox5.SelectedIndex = 1;
}
else{
comboBox5.SelectedIndex = 0;
}
if ((keysetting[0] & 4)>0){
comboBox6.SelectedIndex = 1;
}
else{
comboBox6.SelectedIndex = 0;
}
if ((keysetting[0] & 2) > 0){
comboBox7.SelectedIndex = 1;
}
else {
comboBox7.SelectedIndex = 0;
}
if ((keysetting[0] & 1) > 0) {
comboBox8.SelectedIndex = 1;
}
else {
comboBox8.SelectedIndex = 0;
}
int keynum = keysize[0] % 64 ;
keynumber.Value = keynum;
if ((keysize[0] & 0xc0) == 0x80)
{
comboBox2.SelectedIndex = 3;
}
else
{
if ((keysize[0] & 0xc0) == 0x40)
{
comboBox2.SelectedIndex = 2;
}
else
{
comboBox2.SelectedIndex = 0; //也可能是comboBox2.SelectedIndex = 1
}
}
MessageBox.Show("读取应用的密钥配置信息操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr) + "\r\n密钥配置:" + keysetting[0].ToString("X2") + "\r\n密钥数量:" + keynum.ToString("D"), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void Button22_Click(object sender, EventArgs e)
{
byte[] aidbuf = new byte[3];
byte[] retsw = new byte[2];
string retstr;
if (checkhexstr(textBox5.Text.Trim(), 3, aidbuf) == false)
{
MessageBox.Show("十六进制AID输入错误,请输入3字节的16进制AID!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte keysetting = Convert.ToByte(comboBox4.SelectedIndex * 16 + comboBox5.SelectedIndex * 8 + comboBox6.SelectedIndex * 4 + comboBox7.SelectedIndex * 2 + comboBox8.SelectedIndex);
byte status = desfirechangekeysettings(aidbuf, keysetting, retsw);
retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status == 94)
{
MessageBox.Show("请先执行选择应用AID:" + textBox5.Text.Trim(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
if (status == 63)
{
MessageBox.Show("需要先验证当前应用的主密钥!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else{
if (status > 0)
{
MessageBox.Show("更改应用密钥配置操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
MessageBox.Show("更改应用密钥配置操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void Button19_Click(object sender, EventArgs e)
{
byte[] retsw = new byte[2];
byte[] fidsize = new byte[1]; //返回的文件数量,最大19个
byte[] fidbuf = new byte[16]; //文件ID号数据缓冲,每个ID号占用1个字节,最多16个文件ID号
byte status = desfiregetfileids(fidbuf, fidsize, retsw);
string retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status > 0)
{
MessageBox.Show("搜索当前应用内所有文件ID操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string strls1 = "";
if (fidsize[0] > 0)
{
strls1 = "文件ID:" + fidbuf[0].ToString("D") ;
byte j = 1;
while (j < fidsize[0])
{
strls1 = strls1 + "," + fidbuf[j ].ToString("D") ;
j++;
}
}
MessageBox.Show("搜索当前应用内所有文件ID操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr) + "\r\n文件数量:" + fidsize[0].ToString("D") + "\r\n" + strls1, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void button13_Click(object sender, EventArgs e)
{
byte status; //函数返回值
byte comset; //通讯模式
byte[] accessrights = new byte[2]; //文件访问时的密钥认证方式
byte[] retsw = new byte[2]; //卡片返回值
if (comboBox9.SelectedIndex < 2)
{
comset = Convert.ToByte(comboBox9.SelectedIndex);
}
else { comset = 3; }
accessrights[1] = Convert.ToByte(comboBox10.SelectedIndex * 16 + comboBox11.SelectedIndex);
accessrights[0] = Convert.ToByte(comboBox12.SelectedIndex * 16 + comboBox13.SelectedIndex);
status = desfirechangefilesettings(Convert.ToByte(fileid.Value), comset, accessrights, retsw);
string retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");
if (status == 53)
{
MessageBox.Show("更改文件配置操作返回异常:" + status.ToString("D") + ",说明:CPU卡功能通讯错误,可能是卡拿开重放后未激活或卡不在感应区!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
if (status > 0)
{
MessageBox.Show("更改文件配置操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
MessageBox.Show("更改文件配置操作卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}