/// <summary> /// 外部身份验证 /// </summary> /// <param name="Key"></param> /// <returns></returns> public ApduMsg Auth(byte[] Key) { if (Key.Length != 8) { return(new ApduMsg("身份验证Key长度不正确")); } string RANDOMCMD = "0084000004"; byte[] Random = SendStrCommand(RANDOMCMD); if (Random.Length != 6) { return(new ApduMsg("返回随机数长度不正确")); } byte[] Randomdata = new byte[8]; Array.Copy(Random, 0, Randomdata, 0, 4); List <byte> cmdList = new List <byte>(); cmdList.AddRange(CPUCardHelper.ConverToBytes("00 82 00 00 08")); cmdList.AddRange(CPUCardHelper.Encrypt(Randomdata, Key)); byte[] data = CardSendCommand(cmdList.ToArray()); return(ApduMsg.GetApduByData(data)); }
/// <summary> /// 根据文件标识选择文件ID /// </summary> /// <returns></returns> public ApduMsg SelectFileById(ushort fileId) { string cmd = "00A4000002"; byte[] data = SendStrCommand(cmd + CPUCardHelper.ConvertoHEX(fileId, 4)); return(ApduMsg.GetApduByData(data)); }
public ApduMsg CreateDFFile(ushort fileID, int fileLenght, string FileAccess = "F0F0") { // 执行指令: 80E0 3F01 0D 38 0520 F0F0 95 FFFF 4444463031 //说明: 80E0 :指令类别和指令码; 3F01 :文件标识; 0D:长度; 38 :文件类型 //0520 :文件的空间大小; F0: 读权限; F0: 写权限; // 4444463031 :文件名 DDF01 也就是ASCII码了 //80-E0-00-01-09-38-00-64-F0-F0-95-FF-FF-31 //80,E0,3F,01,0D,38,05,20,F0,F0,95,FF,FF,44,44,46,30,31, //EF01 文件标识 //07 LC data 长度(07) //28 文件类型(二进制) //002A 文件长度 //F00E 读写权限 //FF 保留 //80 不支持线路保护 ApduCommand cmd = new ApduCommand(); cmd.CLA = 0x80; cmd.INS = 0xE0; cmd.SetP1P2(fileID); //构造一个data ,长度,权限, List <byte> data = new List <byte>(); //文件类型 data.Add((byte)CPUFileType.MFDF); //文件长度 data.AddRange(CPUCardHelper.IntConvertTo2Byte(fileLenght)); //data.Add(0x05); //data.Add(0x20); //添加读写权限 //data.AddRange(CPUCardHelper.ConverToBytes(FileAccess)); data.Add(0xF0); data.Add(0xF0); //应用文件ID data.Add(0x95); //保留字 data.Add(0xFF); data.Add(0xFF); //使用文件ID当文件夹名称 //data.AddRange(CPUCardHelper.IntConvertTo2Byte(fileID)); data.AddRange(GetDFNameByID(fileID)); //不支持线路保护 //data.Add(0x80); cmd.Data = data.ToArray(); ApduMsg msg = ApduMsg.GetApduByData(SendStrCommand(cmd)); if (msg.Code == "6A-86") { msg.Msg += "(文件已存在)"; } return(msg); }
/// <summary> /// 根据偏移量,读取当前文件 /// </summary> /// <param name="index">偏移量</param> /// <param name="lenght">长度</param> /// <returns></returns> private ApduMsg ReadFile(int index, int lenght) { //string cmd = "00B0--0000FE"; string cmd = "00B0--{0}--{1}"; //读取文件偏移量 string fileLenghtHexStr = Convert.ToString(index, 16).PadLeft(4, '0'); //读取的长度 string lenghtStr = Convert.ToString(lenght, 16).PadLeft(2, '0'); cmd = string.Format(cmd, fileLenghtHexStr, lenghtStr); return(ApduMsg.GetApduByData(SendStrCommand(cmd))); }
/// <summary> /// 根据文件名称选择 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public ApduMsg SelectFileName(byte[] fileName) { //00A40400 09 A00000000386980701 byte[] dd = CPUCardHelper.ConverToBytes("00A40400"); List <byte> result = new List <byte>(); result.AddRange(dd); result.Add((byte)fileName.Length); result.AddRange(fileName); byte[] cmd = result.ToArray(); byte[] data = CardSendCommand(cmd); return(ApduMsg.GetApduByData(data)); }
/// <summary> /// 创建文件 /// </summary> /// <param name="fileIDHex">文件标识符2字节</param> /// <param name="fileType">枚举文件类型</param> /// <param name="fileLenght">文件长度</param> /// <param name="fileNameHex">文件名称,十六进制</param> /// <param name="FileAccess"></param> /// <returns></returns> public ApduMsg CreateFile(ushort fileID, CPUFileType fileType, int fileLenght, string FileAccess = "0000") { //Demo //80E0-EF01-07-28-002A-F00E-FF-80 //EF01 文件标识 //07 LC data 长度(07) //28 文件类型(二进制) //002A 文件长度 //F00E 读写权限 //FF 保留 //80 不支持线路保护 ApduCommand cmd = new ApduCommand(); cmd.CLA = 0x80; cmd.INS = 0xE0; cmd.SetP1P2(fileID); //构造一个data ,长度,权限, List <byte> data = new List <byte>(); //文件类型 data.Add((byte)fileType); //文件长度 data.AddRange(CPUCardHelper.IntConvertTo2Byte(fileLenght)); //添加读写权限 data.AddRange(CPUCardHelper.ConverToBytes(FileAccess)); //添加文件名 data.AddRange(CPUCardHelper.ConverToBytes("FFFF")); //不支持线路保护 data.Add(0x80); cmd.Data = data.ToArray(); ApduMsg msg = ApduMsg.GetApduByData(SendStrCommand(cmd)); if (msg.Code == "6A-86") { msg.Msg += "(文件已存在)"; } return(msg); }
/// <summary> /// 读余额 /// </summary> public ApduMsg GetBalance(bool IsWallet) { ApduCommand cmd = new ApduCommand(); cmd.CLA = 0x80; cmd.INS = 0x5C; //根据文档,01用于电子存折,02用于电子钱包 if (!IsWallet) { cmd.P2 = 0x01; } else { cmd.P2 = 0x02; } cmd.LE = 0x4; return(ApduMsg.GetApduByData(SendStrCommand(cmd))); }
public ApduMsg SelectDFFile(ushort fileId) { //00-A4-04-00-03-44-46-31-00 string cmd = "00A40400"; List <byte> listdata = CPUCardHelper.ConverToBytes(cmd).ToList(); byte[] data = GetDFNameByID(fileId); byte LC = (byte)(data.Length + 1); listdata.Add(LC); listdata.AddRange(data); listdata.Add(0); //ApduCommand adpCMd = new ApduCommand(listdata.ToArray()); ////adpCMd.LE = 0; byte[] Resdata = CardSendCommand(listdata.ToArray()); return(ApduMsg.GetApduByData(Resdata)); }
/// <summary> /// 根据偏移量,写入数据到当前文件 /// </summary> /// <param name="index"></param> /// <param name="data"></param> /// <returns></returns> private ApduMsg WriteContent(ushort index, byte[] data) { //string fileLenghtHexStr = Convert.ToString(fileLenght, 16).PadLeft(4, '0'); //00D6-0000-02-0102 //0000 文件偏移量 //02 LC,data 长度 //0102数据 //FMCOS写文件说明,若P1点高三位为100,则低五位为短的二进制文件标识符。P2为欲写入的文件偏移量 //若P1点最高位不为1,则P1,P2为欲写入的文件偏移量,所写文件为当前文件 ApduCommand cmd = new ApduCommand(); cmd.CLA = 0x00; cmd.INS = 0xD6; cmd.SetP1P2(index); cmd.Data = data; //List<byte> array = new List<byte>(); //array.Add(0x00); //array.Add(0xD6); ////添加P1 P2参数为文件偏移量 //array.Add((byte)(index / 256)); //array.Add((byte)(index % 256)); ////添加LC,为数据长度 //array.Add((byte)data.Length); ////添加数据 //array.AddRange(data); //ApduMsg msg = ApduMsg.GetApduByData(carder.SendCommand(array.ToArray())); ApduMsg msg = ApduMsg.GetApduByData(SendStrCommand(cmd)); return(msg); }
/// <summary> /// 删除当前文件 删除DF /// </summary> /// <returns></returns> public ApduMsg RemoveDF() { return(ApduMsg.GetApduByData(SendStrCommand("800E000000"))); }
/// <summary> /// 选择MF(顶层目录) /// </summary> /// <returns></returns> public ApduMsg SelectMF() { return(ApduMsg.GetApduByData(SendStrCommand("00A40000023F00"))); // return ApduMsg.GetApduByData(SendStrCommand("00,A4,00,00,00")); }
public ApduMsg SendCommand(string hex) { return(ApduMsg.GetApduByData(SendStrCommand(hex))); }