今天记录一下Android 非接触式M1卡是怎么样改默认密码的,因为这几天刚好帮公司撸了一下,希望能对做NFC开发这一块的兄弟们有所帮助。首先我们先要了解一下为什么要M1卡的基本构造和相关说明,这里我推荐看业余代码工作者的blog,感谢他的分享。

      了解完M1卡的基本构造和相关说明后,知道了M1卡有16个扇区,每个扇区的最后一块是记录KeyA和KeyB还有控制位的。KeyA和KeyB的默认密码都是ffffffffffff,其中KeyA在所有情况下都是不可读的(大多数写机程序里显示的是000000000000)。所以使用默认的密码的M1卡很容易被人模拟,就有了修改默认密码的需求。

       要修改密码我们首先要知道存放密码的是哪一块结构?是怎么样的结构?

      首先我解答一下上面的问题: M1卡存放密码大多数都是在 每一扇区的最后一块,结构是000000000000FF078069ffffffffffff。前12位是是KeyA,中间8位位控制位,后12位为KeyB。

accesscontrol门禁 sqlserver accesscontrol门禁说明书修改密码_修改密码

这里要注意一下了,在修改之前一定要先修改控制位为(08 77 8F 69),要怎么修改呢?我们先去查找厂家给的SDK里面的write和read这两个函数。然后我们先通过调用SDK的mifare.authenticate()这个方法去校验扇区的默认密码,通过后便可调用read()方法读取扇区的数据,接下来就是调用write()方法把我们要修改的数据写进去。这里记得是先修改控制位再去修改密码,顺序不要错了,不然可能会有其他问题。

msgBuffer.delete(0, msgBuffer.length());
                    msgBuffer.append("寻到Mifare卡->UID:").append(mifare.uidToString()).append("\r\n");
                    msgBuffer.append("开始验证第1块密码\r\n");
                    handler.sendEmptyMessage(0);
                    byte[] key = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
                    try {
                        boolean anth = mifare.authenticate((byte) 0x11, Mifare.MIFARE_KEY_TYPE_A, key);
                        if (anth) {                    
                            byte[] readDataBytes ;
                            readDataBytes = mifare.read((byte) 0x11);
                            msgBuffer.append("块11数据:").append(StringTool.byteHexToSting(readDataBytes)).append("\r\n");
                            handler.sendEmptyMessage(0);
                            msgBuffer.append("验证密码成功\r\n");
                            msgBuffer.append("写213496578320到块1\r\n");

//                            handler.sendEmptyMessage(0);
//                            boolean isSuc = mifare.write((byte)0x11, new byte[]{0x22, 0x11, 0x22, 0x44, 0x66, 0x11, 0x22, 0x77, (byte) 0x88, (byte) 0x99, 0x22, 0x55, 0x66, 0x33, 0x44, 0x55});
//                              boolean isSuc = mifare.write((byte)(3&0xFF),new byte[]{(byte) 0xff,(byte) 0xff,(byte) 0xff,(byte) 0xff,(byte) 0xff,(byte) 0xff,0x08,0x77, (byte) 0x8f,0x69, (byte) 0x11,(byte) 0xff,(byte) 0xff,(byte) 0xff,(byte) 0xff,(byte) 0xff});
//                            if (isSuc) {
//                                msgBuffer.append("写成功!\r\n");
//                                msgBuffer.append("读块1数据\r\n");
//                                handler.sendEmptyMessage(0);
                                byte[] readDataBytes1 = mifare.read((byte) 0x13);
                                msgBuffer.append("块1数据:").append(StringTool.byteHexToSting(readDataBytes1)).append("\r\n");
                                handler.sendEmptyMessage(0);
//                            } else {
//                                msgBuffer.append("写失败!\r\n");
//                                handler.sendEmptyMessage(0);
//                                return false;
//                            }
                        }
                        else {
                            msgBuffer.append("验证密码失败\r\n");
                            handler.sendEmptyMessage(0);
                            return false;
                        }

                        handler.sendEmptyMessage(0);

                    } catch (CardNoResponseException e) {
                        e.printStackTrace();
                        return false;
                    }

       菜鸟代码勿喷,要是有高手能简化欢迎留言哈,这样我们就能修改了一个扇区里的密码了。但是一般来说我们都要把每个扇区的每一个密码都进行修改的,这样才能在最大限度的保证安全性。这时候我们其实就可以写一个for循环就好,至于怎么写大家可以试试思想是一样的。