1. 程式人生 > >android 非接觸式M1卡改密碼

android 非接觸式M1卡改密碼

     今天記錄一下Android 非接觸式M1卡是怎麼樣改預設密碼的,因為這幾天剛好幫公司擼了一下,希望能對做NFC開發這一塊的兄弟們有所幫助。首先我們先要了解一下為什麼要M1卡的基本構造和相關說明,這裡我推薦看業餘程式碼工作者的blog,感謝他的分享。

      瞭解完M1卡的基本構造和相關說明後,知道了M1卡有16個扇區,每個扇區的最後一塊是記錄KeyA和KeyB還有控制位的。KeyA和KeyB的預設密碼都是ffffffffffff,其中KeyA在所有情況下都是不可讀的(大多數寫機程式裡顯示的是000000000000)。所以使用預設的密碼的M1卡很容易被人模擬,就有了修改預設密碼的需求。

       要修改密碼我們首先要知道存放密碼的是哪一塊結構?是怎麼樣的結構?

      首先我解答一下上面的問題: M1卡存放密碼大多數都是在 每一扇區的最後一塊,結構是000000000000FF078069ffffffffffff。前12位是是KeyA,中間8位位控制位,後12位為KeyB。

     我現在是需求是根據KeyB來檢驗密碼,所以我要修改的就是KeyB的密碼。這裡要注意一下了,在修改之前一定要先修改控制位為(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迴圈就好,至於怎麼寫大家可以試試思想是一樣的。