Создайте и прочитайте универсальный пропуск NFC Smart Tap в Google Кошельке

Я пытаюсь интегрировать и использовать Google Wallet (API и Android SDK) для создания универсального пропуска с включенным Smart Tap, прочитать его с помощью другого мобильного телефона и расшифровать полезную нагрузку.

ПРЕД:

  1. Учитывая, что Google уже предоставил образец: https://github.com/google-pay/smart-tap-sample-app
  2. Данный образец работает на моем мобильном телефоне, читающем демонстрационный пропуск NFC из Google (см. ссылку README проекта github).
  3. Учитывая это, по URL-адресу https://pub1.pskt.io/c/gn1v07 можно генерировать случайные пропуска NFC, содержащие общедоступную необходимую информацию (CollectorID, закрытый ключ, открытый ключ).
  4. Учитывая, что с пропусками pskt (3) и примером приложения (1), я могу прочитать эти пропуска.

Я не могу прочитать свои специальные пропуска или, если быть точным, я не получаю правильную полезную нагрузку.

Мои текущие пропуски находятся в «Демо-режиме», потому что я хочу убедиться, что они работают, прежде чем просить о публикации. В документации Google неясно, является ли это блокировщиком или что делать в этом случае. Я попытался загрузить открытый ключ pskt (3) (другой версии) в консоль моего кошелька, но все равно не помогло. Идентификатор сборщика — это тот, который у меня есть в консоли моего кошелька Google (преобразованный в байт), а мой идентификатор эмитента был добавлен в список redemptionIssuers. кажется, что smartTapRedemptionValue не прописано в теге, но если я запрашиваю API кошелька, оно есть:

{
  "cardTitle": {
    "defaultValue": {
      "kind": "walletobjects#translatedString",
      "language": "it",
      "value": "$TITLE"
    },
    "kind": "walletobjects#localizedString"
  },
  "classId": "$ISSUER_ID.$CLASS_NAME",
  "genericType": "genericTypeUnspecified",
  "hasUsers": true,
  "header": {
    "defaultValue": {
      "kind": "walletobjects#translatedString",
      "language": "it",
      "value": "$HEADER"
    },
    "kind": "walletobjects#localizedString"
  },  
  "hexBackgroundColor": "#ffffff",
  "id": "$ISSUER_ID.newPassObject3",
  "smartTapRedemptionValue": "if_you_read_this_it's_great!",
  "state": "active",
  "subheader": {
    "defaultValue": {
      "kind": "walletobjects#translatedString",
      "language": "it",
      "value": "$SUBHEADER"
    },
    "kind": "walletobjects#localizedString"
  }
}

Если кто-нибудь знает, спасибо за помощь!

0
0
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел, в чем проблема, и дело было не в пропуске.

TL:DR -> Пример приложения неполный и содержит недостающие части.

Копаясь в документации и различных методах обратного проектирования, я обнаружил использование кода «Тип службы», который был жестко запрограммирован в приложении: https://github.com/google-pay/smart-tap-sample-app/blob/192d1760bd8f44e8142dda6611c2a1314b35595b/app/src/main/java/com/google/smarttapsample/GetDataCommand.java#L37

Здесь установлены карты лояльности (0x03). Если вы хотите, чтобы он работал с универсальными проходами, вам нужно указать Generic (0x12). Кроме того, есть обновление метода GetDataResponse getDecryptedPayload: https://github.com/google-pay/smart-tap-sample-app/blob/192d1760bd8f44e8142dda6611c2a1314b35595b/app/src/main/java/com/google/smarttapsample/GetDataResponse.java#L258

Вам следует добавить «иначе, если» для управления общими карточками:

// Iterate over service NDEF records
for (NdefRecord serviceRecord : serviceNdefRecord.getRecords()) {
    // Check for `ly` type.   
    if (Arrays.equals(serviceRecord.getType(), new byte[]{(byte) 0x6c, (byte) 0x79})) {
        //.... processLoyaltyServiceRecord(serviceRecord);
    } else if (Arrays.equals(serviceRecord.getType(), new byte[]{(byte) 103, (byte) 114})) {
        processGenericServiceRecord(serviceRecord);
    }
}

    private void processGenericServiceRecord(NdefRecord serviceRecord) throws FormatException {
        //in case of general pass `gr` type
        // Get the generic record payload
        NdefMessage genericRecordPayload = new NdefMessage(serviceRecord.getPayload());
        for (NdefRecord generic : genericRecordPayload.getRecords()) {
            // Check for `n` ID = 6e
            if (Arrays.equals(generic.getId(), new byte[]{(byte) 0x6e})) {
                // Get the Smart Tap redemption value
                decryptedSmartTapRedemptionValue = new String(Arrays.copyOfRange(generic.getPayload(), 1, generic.getPayload().length));
            }
        }
    }

И теперь чтение пропуска работает корректно!

Спасибо за предоставление самостоятельного решения. Я изменил исходный код в двух позициях, но пропуск, импортированный по вашей ссылке (pub1.pskt.io/c/gn1v07), не читается. Необходимы ли другие изменения (CollectorID, закрытый ключ, открытый ключ) и где получить информацию? Еще раз спасибо.

Michael Fehr 15.09.2023 07:52

Привет, Михаил, чтобы прочитать пропуск по ссылке, вам необходимо сохранить тип услуги для карт лояльности (карты PSKT - это карты лояльности). Кроме того, если вы нажмете на три точки пропуска (на вашем телефоне), вы увидите идентификатор коллекционера и закрытый ключ. Используйте класс PrivKey в Utils (замените его) и преобразуйте десятичное значение идентификатора сборщика в массив байтов, тогда код должен работать!

N Dorigatti 15.09.2023 10:04

Ух ты, это было легкое изменение, и теперь я могу прочитать карту PassKit NFC Test Pass. Есть ли у вас опыт создания собственных «пользовательских» карт без учетной записи PassKit?

Michael Fehr 15.09.2023 16:24

Да, часть моей текущей работы — создание пропусков из приложения Android (кнопка кошелька), запущенного из примера Google, а также управление классами и пропусками с помощью настольной библиотеки Java. Об этом существует масса документации. Мои карты генерируются в среде google.wallet и не имеют ничего общего с passkit.

N Dorigatti 16.09.2023 13:20

Здравствуйте, к сожалению, я не могу раскрыть полный исходный код. В первом посте есть ссылка на базовое приложение на GitHub, а в комментариях я разместил важные части, к сожалению, не могу предоставить больше.

N Dorigatti 28.09.2023 16:28

Другие вопросы по теме