Как определить APDU для STORE DATA для эмуляции хост-карты?

Я искал в глобальной спецификации платформы информацию о том, как определить APDU для моего приложения, которое будет использовать эмуляцию хост-карты (HCE). В моем приложении должен быть один телефон, который ведет себя как метка NFC через HCE, а другой телефон действует как считыватель NFC. Произвольные данные, которые я пытаюсь передать между телефонами, представляют собой простую строку, содержащую идентификационный номер, но я не совсем уверен, как применить ее в коде. Я посмотрел, что означают разные байтовые команды, но я действительно не уверен, как их применять.

Я думаю, что мне нужно использовать команду STORE DATA, но я не уверен, как это сделать интуитивно, и не совсем понимаю. В настоящее время я смотрю на сторону HCE, а не на сторону читателя.

Это мой код для стороны HCE.

public class SecondaryActivity extends HostApduService {

@Override
public void onDeactivated(int reason) {

}

@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
    String inboundApduDescription;
    byte[] responseApdu;

    if (Arrays.equals(AID_SELECT_APDU, commandApdu)) {
        inboundApduDescription = "Application selected";
        Log.i("HCEDEMO", inboundApduDescription);
        byte[] answer = new byte[2];
        answer[0] = (byte) 0x90;
        answer[1] = (byte) 0x00;
        responseApdu = answer;
        return responseApdu;

    }
    return commandApdu;
}

private static final byte[] AID_SELECT_APDU = {
        (byte) 0x00,
        (byte) 0xA4,
        (byte) 0x04,
        (byte) 0x00,
        (byte) 0x07,
        (byte) 0xF0, (byte) 0x39, (byte) 0x41, (byte) 0x48, (byte) 0x14, (byte) 0x81, (byte) 0x00,
        (byte) 0x00
};

private static final byte[] STORE_DATA = {
        (byte) 0x00,
        (byte) 0xA4,
        (byte) 0x04,
        (byte) 0xA5, // forproprietary data according to the spec
        (byte) 0xE2,
        (byte) 0x66, (byte) 0x39, (byte) 0x41, (byte) 0x48, (byte) 0x14, (byte) 0x81, (byte) 0x00,
        (byte) 0x00
};

private static final byte[] INSTALL = {
        (byte) 0x00,
        (byte) 0x00,
};

}

Как отправить данные с телефона HCE на телефон считывателя? Что мне не хватает? Что должно быть сделано?


person Hazed 2.0    schedule 05.07.2018    source источник


Ответы (1)


Вы можете определить практически любую команду APDU для HCE. Требуется только начальная команда SELECT (по AID). После этого вы можете создать свой собственный набор команд (или попытаться следовать командам ISO/IEC 7816-4), если вы соблюдаете правила ISO/IEC 7816 для структуры APDU команды/ответа и придерживаетесь действительных CLA, INS, и значения слова состояния.

Поскольку вы хотите передать только идентификатор, вы можете отправить этот идентификатор непосредственно в ответ на команду SELECT:

private static final String ID = "1234567890"

@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
    byte[] responseApdu = new byte[] { (byte)0x6F, (byte)0x00 };

    if ((commandApdu != null) && (commandApdu.length >= 4)) {
        if ((commandApdu[0] == (byte)0x00) && (commandApdu[1] == (byte)0xA4) && (commandApdu[2] == (byte)0x04) && (commandApdu[3] == (byte)0x00)) {
            Log.i("HCEDEMO", "Application selected");

            byte[] id = ID.getBytes(Charset.forName("UTF-8"));
            responseApdu = new byte[id.length + 2];
            System.arraycopy(id, 0, responseApdu, 0, id.length);
            responseApdu[id.length] = (byte)0x90;
            responseApdu[id.length + 1] = (byte)0x00;
        }
    }
    return responseApdu;
}
person Michael Roland    schedule 06.07.2018
comment
Хорошо, большое спасибо. Каково значение System.arraycopy(id,0,answer,0,id.length); Я понимаю, что он копирует массив байтов строки идентификатора, но куда? в массив «ответ»? Но это не было инициализировано, и куда это вообще идет? - person Hazed 2.0; 07.07.2018
comment
@ hazed2.0 верно, это осталось от упрощения моего ответа. Он должен был читать responseApdu вместо answer. Я исправил это сейчас. - person Michael Roland; 07.07.2018
comment
Кроме того, должен ли он возвращать commandApdu, почему он не возвращает responseApdu? - person Hazed 2.0; 07.07.2018
comment
@ Hazed2.0 Очевидно, я слишком устал, когда писал этот пост. Исправлено сейчас. - person Michael Roland; 07.07.2018
comment
также как мне отправить apdu в responseApdu? Пожалуйста, ответьте на мою тему здесь stackoverflow.com/questions/51331045/ - person Hazed 2.0; 13.07.2018
comment
Я нигде в своем коде явно не вызывал метод processCommandApdu(). Будет ли он вызываться автоматически при получении правильного SELECT AID? Как я могу проверить, что он был получен... через Log.i? в консоли ничего не печатается. - person Hazed 2.0; 15.07.2018
comment
Я нигде в своем коде явно не вызывал метод processCommandApdu(). Будет ли он вызываться автоматически при получении правильного SELECT AID? Как я могу проверить, что он был получен... через Log.i? в консоли ничего не печатается. Он обнаруживает тег на другом телефоне HCE, но не отвечает. Строка byte[] result = isoDep.transceive(selectApdu(SelectAID)); похоже, не работает должным образом. Мне удалось зарегистрировать полный массив commandApdu, который содержит следующие значения [-92, 4, 0, 7, -14, 57]. - person Hazed 2.0; 15.07.2018
comment
@ Hazed2.0 Если это весь командный APDU, то вашу службу HCE никогда не следует вызывать. Может быть, это только часть массива commandApdu? Кстати. processCommandApdu() вызывается Android для пересылки командных APDU в вашу службу. Вот почему вы должны зарегистрировать свой сервис HCE в манифесте и в XML-файле вашего apdu-сервиса (по его AID). - person Michael Roland; 15.07.2018
comment
Хорошо, неважно, исправил это сейчас, потому что у меня не было «сервиса» в моем манифесте. ProcessCommandApdu теперь успешно вызывается, и данные были получены считывателем, как теперь мне разбить байты и преобразовать их обратно в строку, чтобы получить исходные данные (идентификационный номер)..? - person Hazed 2.0; 15.07.2018
comment
Неважно, я разобрался с этим сейчас. Наконец-то работает!!! Большое вам спасибо за вашу помощь ! - person Hazed 2.0; 15.07.2018
comment
Еще одна вещь: как мне передать идентификатор из другого действия в этот класс HostApduService вместо жесткого кодирования идентификатора, как вы сделали здесь? - person Hazed 2.0; 30.07.2018