2013-10-10 21 views
6

Tôi đang cố gắng đọc một số thông tin từ một thẻ ISO/IEC 14443 Loại A.Android NFC IsoDep đọc nội dung tập tin

Sau khi phân tích thẻ với ứng dụng android NFC TagInfo, tôi phát hiện ra rằng ứng dụng (AID: 15845F) có tệp cụ thể (ID tệp: 01) mà tôi cần.

Tôi đã quản lý để kết nối với thẻ và chọn ứng dụng.

String action = getIntent().getAction(); 
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) 
{ 
    Tag tagFromIntent = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG); 
    Log.i(TAG, Arrays.toString(tagFromIntent.getTechList())); 

    IsoDep isoDep = IsoDep.get(tagFromIntent); 
    try 
    { 
     isoDep.connect(); 

     byte[] SELECT = { 
      (byte) 0x00, // CLA = 00 (first interindustry command set) 
      (byte) 0xA4, // INS = A4 (SELECT) 
      (byte) 0x04, // P1 = 04 (select file by DF name) 
      (byte) 0x0C, // P2 = 0C (first or only file; no FCI) 
      (byte) 0x06, // Lc = 6 (data/AID has 6 bytes) 
      (byte) 0x31, (byte) 0x35,(byte) 0x38,(byte) 0x34,(byte) 0x35,(byte) 0x46 // AID = 15845F 
     }; 

     byte[] result = isoDep.transceive(SELECT); 
     Log.i(TAG, "SELECT: " + bin2hex(result)); 

     if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00)) 
      throw new IOException("could not select application"); 

     byte[] GET_STRING = { 
      (byte) 0x00, // CLA Class 
      (byte) 0xB0, // INS Instruction 
      (byte) 0x00, // P1 Parameter 1 
      (byte) 0x00, // P2 Parameter 2 
      (byte) 0x04 // LE maximal number of bytes expected in result 
     }; 

     result = isoDep.transceive(GET_STRING); 
     Log.i(TAG, "GET_STRING: " + bin2hex(result)); 
    } 
} 

Nhưng truy vấn thứ hai của tôi không thành công với mã lỗi: 6A86 (Thông số không chính xác P1-P2). Tôi đã googled rất nhiều và tìm thấy tài liệu khác nhau (ví dụ: http://bit.ly/180b6tB), nhưng tôi chỉ không thể hiểu, làm thế nào tôi có thể thực hiện các giá trị quyền cho P1P2.


EDIT

Loại thẻ của thẻ sử dụng NFC TagInfo: ISO/IEC 14.443-4 Smart Card, Mifare DESFire EV1 (MF3ICD81)

SELECT lệnh được sử dụng trong mã nguồn thực sự không thành công, nhưng thay vào đó nó trả về một phản hồi 9000. Vì vậy, đây là lý do tại sao tôi cho rằng mọi thứ đều hoạt động tốt.

Bạn nói rằng NFC TagInfo không cung cấp đúng giá trị cho DF-tên, vv Là giá trị 0x313538343546 đúng và làm thế nào bạn tìm thấy nó ra?

Bạn có thể cung cấp cho tôi mô tả ngắn, cách tôi có thể nhận được dữ liệu tôi muốn không? Có bất kỳ ứng dụng Android nào khác mà tôi có thể sử dụng để đọc đúng tên DF, AID không? Về cơ bản, tôi cần lấy ONE tệp trong số ONE đơn đăng ký. Tôi cũng có thể cung cấp một số ảnh chụp màn hình của thông tin được thu thập với NFC TagInfo, nếu cần.


EDIT 2

Tôi đã viết lại các lệnh, nhưng (như bạn đề nghị) giữ chúng trong wrapper APDU. Do đó tôi đã có hai lệnh khác nhau, một cho việc lựa chọn ứng dụng và một lệnh khác để lựa chọn tệp.

private final byte[] NATIVE_SELECT_APP_COMMAND = new byte[] 
{ 
    (byte) 0x90, (byte) 0x5A, (byte) 0x00, (byte) 0x00, 3, // SELECT 
    (byte) 0x5F, (byte) 0x84, (byte) 0x15, (byte) 0x00  // APPLICATION ID 
}; 
private final byte[] NATIVE_SELECT_FILE_COMMAND = new byte[] 
{ 
    (byte) 0x90, (byte) 0xBD, (byte) 0x00, (byte) 0x00, 7, // READ 
    (byte) 0x01,           // FILE ID 
    (byte) 0x00, (byte) 0x00, (byte) 0x00,     // OFFSET 
    (byte) 0x00, (byte) 0x00, (byte) 0x00,     // LENGTH 
    (byte) 0x00 
}; 

Việc tìm kiếm một hướng dẫn cho các lệnh Mifire-DESFire bản địa đã không thành công, vì vậy tôi dính vào các hướng dẫn sau đây: http://noobstah.blogspot.de/2013/04/mifare-desfire-ev1-and-android.html

Hướng dẫn này cung cấp một xác thực thẻ, mà tôi tàn tật, và cũng sử dụng phương pháp thu phát, theo cách hiểu của tôi không phải là cách thích hợp để thực thi lệnh gốc? Phương thức nào, có lẽ là đoạn mã, được sử dụng để thực thi các lệnh gốc? Tôi nên sử dụng Android-Class nào?

Tôi đã viết lại lớp học được cung cấp trong hướng dẫn và tải nó lên pastebin. Sau khi thực hiện lớp tôi đã có kết quả sau.

Select APPLICATION: 9100 
Read DATA: 91AE 

Tại thời điểm này tôi khá khó khăn và không biết tôi nên làm gì tiếp theo. Đã được thực sự là lỗi hoặc thay vì những gì thay đổi trong các truy vấn tôi nên thực hiện, để có được những dữ liệu tôi muốn?

Trả lời

8

Với thông tin bạn đã trích xuất từ ​​NFC TagInfo và các lệnh bạn đang cố gắng sử dụng, tôi cho rằng thẻ là MIFARE DESFire EV1. Chính xác?

Về lệnh lựa chọn của bạn: NFC TagInfo hiện không đọc giá trị tên DF được sử dụng trong bộ lệnh ISO cho DESFire EV1. Vì vậy, tôi giả định rằng tên DF được thiết lập cho ứng dụng này thực sự là 0x313538343546, nếu không lệnh SELECT sẽ thất bại. Tuy nhiên, lưu ý rằng giá trị này không có nghĩa là từ DESFire AID được hiển thị trong NFC TagInfo! Trong thực tế, DF-name là một giá trị riêng biệt được xác định trong quá trình tạo ứng dụng. (Điều này khác với phiên bản DESFire trước đó.)

Về lệnh READ BINARY của bạn: Lệnh bạn đã sử dụng sẽ ngụ ý rằng bạn đã chọn tệp trước đó. Tuy nhiên, bạn chỉ chọn ứng dụng. Vì vậy, bạn sẽ có cần phải ban hành một lệnh SELECT cho các tập tin dữ liệu hoặc sử dụng một ID tập tin ngắn trong READ Binary lệnh:

byte[] READ_BINARY = { 
     (byte) 0x00, // CLA Class 
     (byte) 0xB0, // INS Instruction 
     (byte) 0x80, // P1 (indicate use of SFI) 
     (byte) 0x01, // P2 (SFI = 0x01) 
     (byte) 0x04 // LE maximal number of bytes expected in result 
}; 

Tuy nhiên, khi nói đến DESFire (EV1) tôi đề nghị bạn thích gắn bó với bộ lệnh gốc DESFire (trực tiếp hoặc gói) thay vì sử dụng các APDU ISO 7816-4.

Với bộ lệnh gốc, bạn có đầy đủ chức năng của MIFARE DESFire. Gói lệnh được thực hiện bằng cách nhúng các lệnh DESFire gốc vào một cấu trúc APDU ISO 7816-4. Lệnh gói trông giống như sau:

0x90 CMD 0x00 0x00 LEN CMD-PARAM 0x00 

Nơi CMD là lệnh gốc DESFire và CMD-PARAM là các tham số lệnh. Câu trả lời là:

[DATA] 0x91 STATUS 

Trạng thái ở đâu là mã trạng thái gốc DESFire. Nếu TÌNH TRẠNG là 0xAF, bạn có thể lấy dữ liệu phản ứng còn lại bằng cách phát hành lệnh này:

0x90 0xAF 0x00 0x00 0x00 

Vì vậy, trong trường hợp của bạn, bạn sẽ phát hành một lệnh đơn chọn cho ứng dụng của bạn 0x15845F (tâm thứ tự byte khác nhau!):

0x90 0x5A 0x00 0x00 3 0x5F 0x84 0x15 0x00 
    |SELECT|   |APPLICATION ID| 

Sau đó, bạn muốn đọc các tập tin dữ liệu 0x01 (toàn bộ tập tin, bắt đầu tại offset 0):

0x90 0xBD 0x00 0x00 7 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
    |READ|   |FILE| OFFSET | LENGTH | 

Về câu hỏi của bạn như thế nào để có được những tên ISO DF và ISO FID cho ứng dụng của bạn, bạn có thể thử các lệnh sau:

Chọn ứng dụng chính:

905A00000300000000 

ứng dụng Get bao gồm tên DF của họ:

906D000000 

Chọn ứng dụng của bạn:

905A0000035F841500 

Nhận DESFire FIDs:

906F000000 

Nhận ISO FIDs:

9061000000 

Bạn luôn có thể sử dụng phương thức transceive() của đối tượng IsoDep. IsoDep (tức là ISO/IEC 14443-4) được sử dụng anyways (cho các lệnh DESFire nguyên gốc, cho các lệnh gốc được bao bọc và cho các lệnh ISO 7816-4).

Mã lỗi bạn nhận được từ thẻ (0xAE) cho biết lỗi xác thực (xem bảng dữ liệu này để biết thêm thông tin: DESFire). Do đó, tệp cho phép chỉ đọc được xác thực (xem các điều kiện truy cập được hiển thị trong NFC TagInfo).

Vì vậy, để đọc tệp này, bạn sẽ cần triển khai quy trình xác thực.

+0

Cảm ơn bạn đã phản hồi nhanh! Tôi vừa chỉnh sửa bài đăng của mình và ở cuối bài đăng, có thêm thông tin. – Vilius

+0

Cảm ơn sự giúp đỡ của bạn, nhưng tôi vẫn bị kẹt và tôi vừa chỉnh sửa bài đăng của mình và phục vụ thêm một số thông tin. – Vilius

+0

Tôi đã cập nhật câu trả lời. Rất tiếc, tôi không thể giúp bạn triển khai quy trình xác thực. –

Các vấn đề liên quan