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 )が、 P1とP2の正しい値を実装する方法を理解できませんでした。
編集
NFC TagInfoを使用するカードのタグ タイプ: ISO/IEC 14443-4 スマート カード、Mifare DESFire EV1 (MF3ICD81)
ソース コードで使用されている SELECT コマンドは、実際には失敗しませんでしたが、代わりに 9000 応答を返しました。これが、すべてが正常に機能していると想定した理由です。
あなたは、NFC TagInfoが DF 名などの正しい値を提供しないと述べました。値0x313538343546は正しいですか?どのようにしてそれを見つけましたか?
必要なデータを取得する方法を簡単に説明していただけますか? 正しい DF 名、AID などを読み取るために使用できる他の Android アプリはありますか? 基本的に、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
この時点で、私はかなり立ち往生しており、次に何をすべきかわかりません。必要なデータを取得するために、実際にエラーが発生したか、クエリでどのような変更を実行する必要がありますか?