8

ISO/IEC 14443 タイプ Aカードから情報を読み取ろうとしています。

Android アプリNFC TagInfoでカードを分析した後、アプリケーション (AID: 15845F) に必要な特定のファイル (ファイル ID: 01) があることがわかりました。

私はすでにカードに接続してアプリケーションを選択することができました.

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));
    }
}

しかし、2 番目のクエリはエラー コード 6A86 (パラメーター P1-P2 が正しくありません) で失敗します。私はすでに多くのことをグーグルで検索し、さまざまなドキュメントを見つけました (例: http://bit.ly/180b6tB )が、 P1P2の正しい値を実装する方法を理解できませんでした。


編集

NFC TagInfoを使用するカードのタグ タイプ: ISO/IEC 14443-4 スマート カード、Mifare DESFire EV1 (MF3ICD81)

ソース コードで使用されている SELECT コマンドは、実際には失敗しませんでしたが、代わりに 9000 応答を返しました。これが、すべてが正常に機能していると想定した理由です。

あなたは、NFC TagInfoが DF 名などの正しい値を提供しないと述べました。値0x313538343546は正しいですか?どのようにしてそれを見つけましたか?

必要なデータを取得する方法を簡単に説明していただけますか? 正しい DF 名、AID などを読み取るために使用できる他の A​​ndroid アプリはありますか? 基本的に、1 つのアプリケーションから 1 つのファイルを取得する必要あります必要に応じて、 NFC TagInfoで収集された情報のスクリーンショットを提供することもできます。


編集2

私はコマンドを書き直しましたが、(あなたが提案したように) それらを APDU ラッパーに保持しました。したがって、アプリケーションの選択用とファイルの選択用の2つの異なるコマンドができました。

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
};

ネイティブの Mifire- Desfireコマンドのチュートリアルを検索してもうまくいかなかったので、次のチュートリアルに固執します。

このチュートリアルでは、私が無効にしたカード認証を提供し、また、ネイティブ コマンドを実行するための適切な方法ではないトランシーバーメソッドを使用していますか? ネイティブ コマンドの実行に使用される方法 (コード スニピットを含む) はどれですか? どの Android クラスを使用すればよいですか?

チュートリアルで提供されているクラスを書き直して、pastebinにアップロードしました。クラスを実行した後、次の結果が得られました。

Select APPLICATION: 9100
Read DATA: 91AE

この時点で、私はかなり立ち往生しており、次に何をすべきかわかりません。必要なデータを取得するために、実際にエラーが発生したか、クエリでどのような変更を実行する必要がありますか?

4

1 に答える 1

9

NFC TagInfo から抽出した情報と使用しようとしているコマンドを考えると、カードは MIFARE DESFire EV1 であると思います。正しい?

選択コマンドについて: NFC TagInfo は現在、DESFire EV1 の ISO コマンド セットで使用されている DF 名の値を読み取っていません。したがって、このアプリケーション用にセットアップされた DF 名は実際には 0x313538343546 であると想定します。そうでない場合、SELECT コマンドは失敗するはずです。ただし、この値は、NFC TagInfo に表示される DESFire AID からは決して導出できないことに注意してください! 実際、DF-name は、アプリケーションの作成時に定義された別の値です。(これは以前の DESFire バージョンとは異なります。)

READ BINARY コマンドについて: 使用したコマンドは、以前にファイルを選択したことを意味します。ただし、アプリケーションのみを選択しました。したがって、データ ファイルに対して SELECT コマンドを発行するか、READ BINARY コマンド内で短いファイル ID を使用する必要があります。

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
};

ただし、DESFire (EV1) に関しては、ISO 7816-4 APDU を使用する代わりに、DESFire ネイティブ コマンド セット (ダイレクトまたはラップ) に固執することをお勧めします。

ネイティブ コマンド セットを使用すると、MIFARE DESFire のすべての機能を利用できます。コマンドのラッピングは、ネイティブの DESFire コマンドを ISO 7816-4 APDU 構造に埋め込むことによって行われます。ラッピング コマンドは次のようになります。

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

CMD はネイティブ DESFire コマンドで、CMD-PARAM はコマンド パラメータです。応答は次のとおりです。

[DATA] 0x91 STATUS

status は、ネイティブの DESFire ステータス コードです。STATUS が 0xAF の場合、次のコマンドを発行して残りの応答データを取得できます。

0x90 0xAF 0x00 0x00 0x00

したがって、あなたの場合、アプリケーション 0x15845F に対して select application コマンドを発行します (異なるバイト順序に注意してください!)。

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

次に、データ ファイル 0x01 (ファイル全体、オフセット 0 から開始) を読み取ります。

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

アプリケーションの ISO DF 名と ISO FID を取得する方法に関する質問については、次のコマンドを試すことができます。

マスター アプリケーションを選択:

905A00000300000000

DF 名を含むアプリケーションを取得します。

906D000000

アプリケーションを選択してください:

905A0000035F841500

DESFire FID を取得します。

906F000000

ISO FID を取得します。

9061000000

IsoDep オブジェクトの transceive() メソッドはいつでも使用できます。IsoDep (つまり、ISO/IEC 14443-4) はとにかく使用されます (ネイティブ DESFire コマンド、ラップされたネイティブ コマンド、および ISO 7816-4 コマンドの場合)。

カードから受け取ったエラー コード (0xAE) は、認証エラーを示します (詳細については、このデータシートを参照してください: DESFire )。したがって、ファイルは認証された読み取り専用を許可します (NFC TagInfo に示されているアクセス条件を参照してください)。

したがって、このファイルを読み取るには、認証手順を実装する必要があります。

于 2013-10-10T14:54:13.357 に答える