g***@126.com
g***@126.com
  • 发布:2019-02-15 14:54
  • 更新:2022-10-30 22:43
  • 阅读:13645

android NFC MifareClassic 读IC卡加密扇区方法

分类:HBuilderX

近段时间在做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权限。

4 关注 分享
1***@163.com 2***@qq.com 8***@qq.com 刘

要回复文章请先登录注册

1***@qq.com

1***@qq.com

请问作者可以分享一下 写卡的案例嘛。
2022-10-30 22:43
4***@qq.com

4***@qq.com

回复 7***@qq.com :
感谢你的分享,已实践或以正常读取加密扇区数据,请问如何写入
2021-09-15 15:30
2***@qq.com

2***@qq.com

MifareClassic.get(tag)读出来为什么是undefined
2021-07-13 18:59
2***@qq.com

2***@qq.com

有人修改成读m1卡吗?
2021-07-07 17:44
xiaoE

xiaoE

你好,附件文件不存在了,可以再发一下吗?谢谢
2021-05-11 16:37
xiaoE

xiaoE

回复 7***@qq.com :
扇区数,块数,大小都可以读到,但是调用 authenticateSectorWithKeyA 和readBlock 都返回null是什么原因,密码是默认密码[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
2021-05-11 16:35
2***@qq.com

2***@qq.com

回复 霍霍 :
同样问题,有偿求解决
2021-02-25 16:50
9***@qq.com

9***@qq.com

回复 嗯啊 :
同样的问题,你们解决了吗?
2021-01-28 15:47
6***@qq.com

6***@qq.com

回复 嗯啊 :
请问你问题解决了吗?我这个也是,读出来是android.nfc.action.TAG_DISCOVERED,所以一直进不去
2021-01-25 09:43
嗯啊

嗯啊

intent.getAction()=="android.nfc.action.TECH_DISCOVERED" 为什么这句判断进不去啊
2021-01-19 17:03