近段时间在做android下NFC的M1卡的加密扇区的读取,参考了Android_磊子的操作基础内容,但是涉及到MifareClassic类操作验证未能找到相关资料,后来查看了MifareClassic类的源代码和基于android原生案例,实现了加密扇区读取。分享下代码,希望对大家有帮助。
对于NFC操作的基本部分有很多资料都一样的,这里不再赘述,仅简单介绍MifareClassic验证和读取的过程
1、创建MifareClassic对象,MifareClassic.get(tag);
2、建立MifareClassic类连接,MifareClassic.connect();
3、对扇区(0-15)进行验证,按KeyA和KeyB两种验证,
(1) MifareClassic.authenticateSectorWithKeyA(sector,key);
其中sector为扇区号,key为6字节验证码,此处Key需要处理为-128至127的字节,开始使用0x00-0xFF会报错
(2) MifareClassic.authenticateSectorWithKeyB(sector,key);
其中sector为扇区号,key为6字节验证码,此处Key需要处理为-128至127的字节,开始使用0x00-0xFF会报错
4、按块(sector*4+i)读取扇区内的16Byte内容,MifareClassic.readBlock(Block);
Block0=sector×4+0;
Block1=sector×4+1;
Block2=sector×4+2;
Block3=sector×4+3;
5、关闭MifareClassic连接,MifareClassic.close();
MifareClassic读取代码
//MifareClassic读取代码
readData:function(intent){
var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
var techList = tag.getTechList();
var bisMfc=false;
for(var i=0;i<techList.length;i++){
if(techList[i].indexOf('MifareClassic')>=0){
bisMfc=true;
break;
}
}
if(!bisMfc){
this.ICERROR='卡片类型错误!';
return;
}
var mfc=MifareClassic.get(tag);
if(!mfc){
this.ICERROR='卡片获取错误!';
return;
}
mfc.setTimeout(3000);
if(!mfc.isConnected()){
try{
invoke(mfc,'connect');
}catch(e){
this.ICERROR='卡片连接错误!';
return;
}
}
try{
this.ICUID=this.ByteArrayToHexString(tag.getId());
var cmdBytes=this.HexStringToByteArray(this.keyVal);
var auth=false;
if(this.keyType=="A"){
auth=invoke(mfc,"authenticateSectorWithKeyA",parseInt(this.sector),cmdBytes);
}else{
auth=invoke(mfc,"authenticateSectorWithKeyB",parseInt(this.sector),cmdBytes);
}
if(!auth){
this.ICERROR='扇区验证失败';
return;
}
var sectorData=[];
var tmpRet;
this.ICData='IC卡扇区数据>>';
for(var i=0;i<4;i++){
tmpRet=invoke(mfc,"readBlock",this.sector*4+i);
this.ICData=this.ICData+'\n';
this.ICData=this.ICData+this.ByteArrayToHexString(tmpRet);
sectorData.push.apply(sectorData,tmpRet);
}
console.log(this.ByteArrayToHexString(sectorData));
this.ICERROR='读卡完成';
}catch(e){
this.ICERROR=e.message;
console.error(e);
}finally{
mfc.close();
}
}
//Key处理函数
HexStringToByteArray:function(instr) {
var hexA = new Array();
var pos = 0;
var len = instr.length/2;
for(var i=0; i<len; i++)
{
var s = instr.substr(pos, 2);
var v = parseInt(s, 16);
if(v>=128)
v=v-256;
hexA.push(v);
pos += 2;
}
return hexA;
}
项目是基于nui-app项目的vue测试通过的,附件共享了vue文件。
项目需设置android.permission.NFC权限。