|
|
1
Andres Carmona
6 年前
卡驱动程序中的结构块:
-
结构块为(ICC、IC、应用程序标识……):
页眉:“文件2(0501h,0502h…)字节“+”类型(DATA0或SigNED-1)1字节“+”长度2字节“+数据(读卡):
-
ICC、IC卡和卡不需要签名,所以0501到0522(不是050E),签名块文件对于授权是必需的,但对于读取字节文件和创建二进制文件则不是必需的。
-
读取FID的递归:
(fid fid:fid.values())的{
system.out.println(fid.getid());
//未读取03F00和0500非文件
如果(!)fid.getid()。等于(“3f,00”)&!fid.getid().equals(“05,00”)){
b=读卡(r,channel,fid.getid());
//头块文件
byte[]htba=operationhelper.hextobytear(fid.getid());
byte[]sizebyte=bytebuffer.allocate(4).putint(b.length).array();
headerblock[0]=htba[0];//id文件字节1
headerblock[1]=htba[1];//id文件字节2
标题块〔2〕=0;//类型文件数据
headerblock[3]=size byte[2];//大小文件字节1
headerblock[4]=size byte[3];//大小文件字节2
尝试{
filetgd.write(headerblock);
写文件(b);
//添加签名文件
如果(!)fid.getid()。等于(“00,02”)&&!fid.getid().equals(“00,05”)。
& & &!fid.getid()。等于(“c1,00”)&&!fid.getid().equals(“c1,08”)。
& & &!fid.getid().equals(“05,0e”)){
PerformHashFile(R,通道);
B=签名(R,通道);
SigByth= ByTeffSuff.Dead(4).PutIt(b长度).ARARY();
headerblock[0]=htba[0];
headerblock[1]=htba[1];
HeaderBlock[2]=1;
headerblock[3]=大小字节[2];
HeaderBlock[4]=大小字节[3];
filetgd.write(headerblock);
写文件(b);
}
}catch(异常E){
e.printstacktrace();
}
}
}
-
读取数据:
public static byte[]readcard(responseapdu r,cardchannel channel,string fid){
bytearrayOutputstream dataResponseBuffer=new bytearrayOutputstream();
尝试{
//r=channel.transmit(new commandapdu(0x00,0x84,0x00,0x00,operationhelper.hextobytear)(“6f,07,00,00,00,00,00,00,00,a4,02,0c,02,05,04”));
/**
*获取参数
*
*标题
*CLA - 00
*INS—A4
*P1—02
*P2-0C
*数据-00,02//6C,00,00,00,00,08,01,00,00,00
*数据偏移- 00
*数据长度-电车长度
*
*/
//r=channel.transmit(new commandapdu(0x00,0xA4,0x02,0x0C,operationhelper.hextobytear(“00,02”),0x00,0x02));
如果(!)fid.equals(“00,02”)&!fid.等于(“00,05”))
//选择仅限中频定位
R=channel.transmit(new commandapdu(0x00,0xA4,0x04,0x0C,operationhelper.hextobytear)(“FF,54,41,43,48,4F”),0x00,0x06));
//选择EF
R=channel.transmit(new commandapdu(0x00,apducommand.select_file.getcommand(),0x02,0x0C,operationhelper.hextobytear(fid),0x00,0x02));
布尔值结束=真;
INT P1= 0x00;
INT P2= 0x00;
字节le=字节值((字节)255);
int大小=0x00;
做{
R=channel.transmit(new commandapdu(0x00,apducommand.read_binary.getcommand(),p1,p2,(le<0)?乐和255;LE)
开关(r.getsw1()){
案例0x90:
dataResponseBuffer.write(r.getData());
大小+=(le<0)?le.intValue()&255:le.intValue();
byte[]offsetarray=bytebuffer.allocate(4).putint(size).array();
p1=(offsetarray[2]<0)?offsetarray[2]和255:offsetarray[2];
p2=(偏移阵列[3]<0)?offsetarray[3]和255:offsetarray[3];
断裂;
案例0x67/,103年12月
断裂;
//正常进程xx=启用响应的字节数
案例0x61:
/*
nuevalong=byte.valueof(codigoError[1]);
*/
断裂;
//参数不正确(超出ef)
案例0x6a:
如果(r.getsw2()==0x86)
system.out.println(“参数p1-p2不正确”);
断裂;
/不正确长,SW2=精确长。如果不返回字段数据
案例0X6C://108年12月
//nuevalong=byte.valueof(codigoError[1]);
如果(r.getsw2()==0x86)
system.out.println(“参数p1-p2不正确”);
断裂;
判例0x69/(108年12月)
结束=假;
断裂;
判例0x6B/(107年12月)
结束=假;
/*
int div=(le<0)?le.intValue()&255:le.intValue();
大小=div;
le=byte.valueof((byte)(div/2));
尺寸+= LE;
如果(LE .ByTaleVe()= =(字节)0){
le=byte.valueof((byte)1);
结束=假;
}
offsetarray=bytebuffer.allocate(4).putint(size).array();
enter=integer.valueof(bytearraysize4point(offsetarray));
p1=(offsetarray[2]<0)?offsetarray[2]和255:offsetarray[2];
p2=(偏移阵列[3]<0)?offsetarray[3]和255:offsetarray[3];
*/
断裂;
违约:
断裂;
}
}(结尾);
}捕获(cardexception e1){
e1.printstacktrace();
}捕获(IOException E){
e.printstacktrace();
}
返回dataResponseBuffer.ToByTearray();
< /代码>
}/P>
5.根据开关内的文件进行错误处理。
-
结构块是(ICC、IC、应用程序标识……):
头:“文件2(0501h,0502h…..)字节”+“类型(数据-0或有符号-1)1字节”+“长度2字节”+数据(读卡):
-
ICC、IC卡和卡不需要签名,所以0501到0522(不是050E),签名块文件对于授权是必需的,但对于读取字节文件和创建二进制文件则不是必需的。
-
读取FID的递归:
for (Fid fid : Fid.values()) {
System.out.println(fid.getId());
// not read 03f00 and 0500 not files
if(!fid.getId().equals("3f,00") && !fid.getId().equals("05,00")){
b = readCard(r, channel, fid.getId());
// header block file
byte[] htba = OperationHelper.hexToByteAr(fid.getId());
byte[] sizeByte = ByteBuffer.allocate(4).putInt(b.length).array();
headerBlock[0] = htba[0]; // id file byte 1
headerBlock[1] = htba[1]; // id file byte 2
headerBlock[2] = 0; // type file data
headerBlock[3] = sizeByte[2]; // size file byte 1
headerBlock[4] = sizeByte[3]; // size file byte 2
try{
fileTGD.write(headerBlock);
fileTGD.write(b);
// add signature file
if (!fid.getId().equals("00,02") && !fid.getId().equals("00,05")
&& !fid.getId().equals("C1,00") && !fid.getId().equals("C1,08")
&& !fid.getId().equals("05,0E")){
performHashFile(r, channel);
b = signature(r, channel);
sizeByte = ByteBuffer.allocate(4).putInt(b.length).array();
headerBlock[0] = htba[0];
headerBlock[1] = htba[1];
headerBlock[2] = 1;
headerBlock[3] = sizeByte[2];
headerBlock[4] = sizeByte[3];
fileTGD.write(headerBlock);
fileTGD.write(b);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
-
读取数据:
public static byte[] readCard( ResponseAPDU r, CardChannel channel, String fid){
ByteArrayOutputStream dataResponseBuffer = new ByteArrayOutputStream();
try {
//r = channel.transmit(new CommandAPDU(0x00, 0x84, 0x00, 0x00, OperationHelper.hexToByteAr("6f,07,00,00,00,08,00,00,00,00,00,a4,02,0c,02,05,04")));
/**
* GetParameters
*
* Headers
* CLA - 00
* INS - A4
* P1 - 02
* P2 - 0C
* DATA - 00,02 //6C,00,00,00,00,08,01,00,00,00
* dataOffset - 00
* dataLength - length of trama
*
*/
//r = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x02, 0x0C, OperationHelper.hexToByteAr("00,02"), 0x00, 0x02));
if (!fid.equals("00,02") && !fid.equals("00,05"))
//select MF - Only positioning
r = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x04, 0x0C, OperationHelper.hexToByteAr("ff,54,41,43,48,4f"), 0x00, 0x06));
// select EF
r = channel.transmit(new CommandAPDU(0x00, APDUCommand.SELECT_FILE.getCommand(), 0x02, 0x0C, OperationHelper.hexToByteAr(fid), 0x00, 0x02));
boolean end = true;
int p1 = 0x00;
int p2 = 0x00;
Byte le = Byte.valueOf((byte) 255);
int size = 0x00;
do {
r = channel.transmit(new CommandAPDU(0x00, APDUCommand.READ_BINARY.getCommand(), p1, p2, (le < 0) ? le & 255 : le));
switch (r.getSW1()) {
case 0x90:
dataResponseBuffer.write(r.getData());
size += (le < 0) ? le.intValue() & 255 : le.intValue();
byte[] offsetarray = ByteBuffer.allocate(4).putInt(size).array();
p1 = (offsetarray[2] < 0) ? offsetarray[2] & 255 : offsetarray[2];
p2 = (offsetarray[3] < 0) ? offsetarray[3] & 255 : offsetarray[3];
break;
case 0x67: // dec 103
break;
// normal process XX = number of bytes for response enabled
case 0x61:
/*
nuevaLong = Byte.valueOf(codigoError[1]);
*/
break;
// incorrect parameters (out of EF)
case 0x6a:
if (r.getSW2() == 0x86)
System.out.println("Parameters P1-P2 incorrects");
break;
// incorrect long, sw2 = exact long. If not return field data
case 0x6c: //dec 108
//nuevaLong = Byte.valueOf(codigoError[1]);
if (r.getSW2() == 0x86)
System.out.println("Parameter P1-P2 incorrects");
break;
case 0x69: //dec 108
end = false;
break;
case 0x6b: //dec 107
end = false;
/*
int div = (le < 0)? le.intValue() & 255: le.intValue() ;
size -= div;
le = Byte.valueOf((byte) (div / 2));
size += le;
if (le.byteValue() == (byte) 0) {
le = Byte.valueOf((byte) 1);
end = false;
}
offsetarray = ByteBuffer.allocate(4).putInt(size).array();
entero = Integer.valueOf(byteArraySize4ToInt(offsetarray) );
p1 = (offsetarray[2] < 0)? offsetarray[2] & 255: offsetarray[2];
p2 = (offsetarray[3] < 0)? offsetarray[3] & 255: offsetarray[3];
*/
break;
default:
break;
}
} while (end);
} catch (CardException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return dataResponseBuffer.toByteArray();
}
5.根据开关内的文件进行错误处理。
|