Справочный материал для ArmSoM: полное техническое содержание китайского Rockchip Android Remote key Provisioning Guide, документ 747, черновик V1.1 от 16 страниц. Обложка двуязычная, технический текст китайский. Отдельного английского источника нет; английский, русский и немецкий переведены с китайского, все четыре используют девять исходных рисунков. Аппаратура ArmSoM и действующие аккаунты Google не проверялись. Совпадение современных правил GMS/VSR, API и инструментов с материалом 2023 года не заявляется. Проверяйте BSP, защищённую аппаратуру и требования авторизованных партнёров.
Неясности источника и границы применения
- Правило безопасной загрузки/тестовой регистрации на странице 15 сомнительно и отмечено в тексте. Регистрация
is_test=trueпостоянна, её нельзя использовать как пробу. Утверждение о производственных сертификатах всех зарегистрированных устройств требует разграничения с постоянной тестовой регистрацией. - Страница 10 называет ключ шифрования закрытым, страница 13 говорит о шифровании «в открытый ключ устройства». Формулировки неточны. Обсуждаются данные открытого ключа в CSR, а не разрешение извлечения закрытого ключа. Отмена HAL-шифрования этих данных в Android 14 не делает закрытые ключи читаемыми.
- В исходном curl имена JSON-полей без кавычек; пример сохранён, но не считается исполняемым. Перед исправлением проверьте авторизованную схему API. Относительный путь
./data/local/tmp/...требует проверки текущего каталога. Псевдокод смешивает C/Python и неверные переносы; он поясняет условия, но не компилируется. - Соединены мягкие переносы PDF в командах, JSON-строках, путях и gtest_filter без изменения флагов, хешей, заполнителей и кодов. Авторство Git сохранено как история кода, не контакты. OAuth-разрешения, загрузки, обновления и регистрация меняют внешние данные; здесь они не выполнялись.
- Открытый ключ в CSR не разрешает произвольные изменения: ограничивайте запись и резервируйте данные. Защищайте OAuth-данные, ключи сервисных аккаунтов и токены. Не включайте
--cache-tokenна общих компьютерах. Тестовый корень не является производственным; сброс удаляет пользовательские данные. - В «каждые X устройств» X не задан; частота выборки не выдумана. Отсутствие задержки и правила RemoteProvisioner/API/GMS относятся к дате источника, не являются гарантией сервиса.
Обзор
Remote Key Provisioning (RKP) переносит предоставление ключей с завода в беспроводной канал. Оно сочетает извлечение открытого ключа на заводе, удалённую выдачу сертификатов и короткий срок их действия. В инфраструктуре аттестации Android это укрепляет цепочку доверия и облегчает восстановление доверия к устройству после уязвимостей.

Рисунок 1. Процесс RKP
На заводе OEM из каждого устройства извлекают уникальный открытый ключ; изготовитель загружает его в серверную систему Google. Устройство запрашивает сертификаты ключей аттестации, доказывая серверу владение своим закрытым ключом. Сервер проверяет открытый ключ и подписывает сертификаты устройства.
Согласно источнику, устройства, выпущенные с Android 13 или новее на чипсетах VSR (Vendor Software Requirements) 12 или новее, должны поддерживать RKP. Три основных этапа: настройка Android Partner API, извлечение запросов подписи сертификата (CSR), загрузка CSR.
Быстрый старт: если Android Partner API уже настроен, выполните процесс RKP следующими командами. Извлеките CSR:
adb shell rkp_factory_extraction_tool --output_format build+csr > csrs.json
Загрузите CSR:
./device_info_uploader.py --credentials /secure/storage/cred.json --json-csr csrs.json --cache-token --company-id COMPANY_ID
Запустите тест GTS:
run gts -m GtsGmscoreHostTestCases
Примечание: на момент руководства RKP дополняет, а не заменяет заводской ключ аттестации.
Проверить наличие записанного ключа аттестации можно так:
adb push VtsAidlKeyMintTargetTest /data/local/tmp/
adb shell chmod +x /data/local/tmp/VtsAidlKeyMintTargetTest
adb shell
su
./data/local/tmp/VtsAidlKeyMintTargetTest --gtest_filter=PerInstance/AttestKeyTest.RsaAttestedAttestKeys/0_android_hardware_security_keymint_IKeyMintDevice_default
Соберите VtsAidlKeyMintTargetTest командой mm в hardware/interfaces/security/keymint/aidl/vts/functional.
1. Настройка Android Partner API
Android Partner API — API проекта Google Cloud (GCP) с поддержкой учётных записей пользователей. Можно повторно использовать cred.json от других сервисов Partner API. При первом подключении выполните процедуру настройки; создайте OAuth 2.0 client ID для проекта GCP и скачайте его как cred.json.
Доступ к упомянутым инструкциям имеют только подписанты MADA или вариантов EMADA, TMADA, TADA с лицензией распространения GMS. Точно соблюдайте их процедуру. Для новой настройки сначала запросите активацию Android Partner API, затем включите API в GCP.
2. Извлечение запросов подписи сертификата
При изготовлении извлеките из каждого устройства CSR с его открытым ключом. SDK поддерживает командную строку и заводской инструмент.
2.1. Командная строка
Эталонный инструмент Google rkp_factory_extraction_tool включён в прошивку SDK. Его вывод записывают в отдельный файл. Извлеките CSR устройства:
adb shell rkp_factory_extraction_tool --output_format build+csr > csrs.json
Исходник: system/security/provisioner/rkp_factory_extraction_tool.cpp; при необходимости его можно адаптировать.
Параметры командной строки
Инструмент заводского извлечения принимает параметры:
| Параметр | Описание |
|---|---|
| –test_mode | Тестовый режим: IRemotelyProvisionedComponent создаёт временный ключ. Полученные данные непригодны для загрузки. |
| –self_test | Получить тестовый CSR и проверить той же логикой, которой VTS проверяет чипсеты. |
| –output_format | csr (по умолчанию): структура запроса CBOR. build+csr: JSON-строка с отпечатком сборки и запросом CBOR для отслеживания соответствия CSR устройствам. |
Коды завершения
Инструмент использует следующие коды завершения:
| Код | Результат |
|---|---|
| 0 | Успех |
| 1 | Неожиданная ошибка выполнения; описание в stderr. |
| -1 | Неверные параметры; описание в stderr. |
2.2. Заводской инструмент
Убедитесь, что оба каталога содержат следующие коммиты.
hardware/rockchip/keymaster4:
commit 2a1c90a031f02964c05a66ba8aa971da528782e8
Author: Wu Liangqing <wlq@rock-chips.com>
Date: Fri May 19 01:26:20 2023 +0000
add rockchip_rkp_factory_extraction_tool arm32 version.
Signed-off-by: Wu Liangqing <wlq@rock-chips.com>
Change-Id: Id511b1e9277eec1073c0ae523e3065826811d9cd
device/rockchip/common:
commit 5b2b3c61d51e93cee1ce42e937ee1cace5b258fd
Author: Bian Jin chen <kenjc.bian@rock-chips.com>
Date: Sat May 6 15:48:30 2023 +0800
gms : Add rockchip_rkp_factory_service for factory MP.
Signed-off-by: Bian Jin chen <kenjc.bian@rock-chips.com>
Change-Id: I86f8a7a78dad7e62e78ebc6e938e9259178d1e04
-
Сначала запишите серийный номер, затем перезагрузите устройство. При первой загрузке с номером
rockchip_rkp_factory_serviceсоздаёт CSR устройства в разделе vendor, откуда его нельзя получить напрямую. -
Откройте KeyboxWriter-v1.55 из
RKTools\windows\KeyboxWriter-v1.55.7zи выберите записываемый ключ Google.

- Откройте настройки и выберите каталог на ПК для сохранения RKP CSR.

- Переведите устройство в режим прошивки loader и нажмите «Старт».

CSR устройства сохраняется в выбранном каталоге, как показано ниже.

Формат имени CSR:
серийный-номер-конкретное-время.json (номер, затем отметка времени).
Важно:
- Запись ключа Google до серийного номера вызывает ошибку чтения RKP CSR, показанную ниже.

- После записи серийного номера выполните обычную загрузку, снова войдите в loader и получите CSR через KeyboxWriter.
3. Загрузка запросов подписи сертификата
Раздел описывает загрузку CSR в серверную систему Google.
- Подготовьте среду и установите зависимости:
pip3 install google-auth==2.13.0 requests==2.28
Скачайте device_info_uploader.py.
-
Используйте извлечённый
csrs.json. -
Найдите
COMPANY_IDдля команды загрузки: войдите в Android Partner Approvals и откройте метаданные компании в Builds > Metadata. Ниже пример.

Рисунок 2. ID компании в Partner Approvals
- Загрузите сведения устройства:
batchUploadдля новых устройств,batchUpdateдля обновления существующих регистраций. Три варианта: скриптdevice_info_uploader.pyс пользователем GCP, тот же скрипт с сервисной учётной записью GCP либо прямой вызов Android Partner API через curl.
Вариант 1: device_info_uploader.py с учётной записью GCP
Используется скрипт загрузки.
- Запустите скрипт, как в примере:
./device_info_uploader.py --credentials /secure/storage/cred.json --json-csr csrs.json --cache-token --company-id COMPANY_ID
Аутентификация --credentials требует локального браузера с JavaScript. Для удалённого терминала, например SSH, используйте сервисную учётную запись: создайте её в Google Cloud, добавьте в список разрешённых, скачайте JSON-ключ и используйте --credentials-keyfile keyfile.json.
Замените /secure/storage/cred.json путём к своим данным доступа. --cache-token сохраняет токен на локальном диске. Не применяйте его при небезопасном хранении, например на общем компьютере.
Форматируйте csrs.json, как ниже: это формат stdout команды rkp_factory_extraction_tool --output_format build+csr.
{"build_fingerprint":"YOUR_FINGERPRINT","csr":"YOUR_CERTIFICATE_REQUEST"}
-
Дождитесь URL входа в выводе скрипта.
-
Откройте URL в новой вкладке браузера для входа Google. Выберите корпоративный аккаунт формата
android-partner-api@company.com, как показано.

Рисунок 3. Выбор аккаунта
- Нажмите «Разрешить», чтобы предоставить тестовому приложению доступ к просмотру и управлению сведениями партнёрских устройств.

Рисунок 4. Разрешение доступа к аккаунту Google
Вариант 2: device_info_uploader.py с сервисной учётной записью GCP
Запустите device_info_uploader.py с csrs.json и ключом my-project-0000000000-ffffffffffff.json, скачанным из Service Account Credentials:
./device_info_uploader.py --credentials-keyfile /secure/storage/my-project-0000000000-ffffffffffff.json --json-csr csrs.json --company-id COMPANY_ID
Вариант 3: прямой вызов Android Partner API через curl
Вызовите API и загрузите файл через curl по примеру источника:
curl -s -X POST -H "Content-Type: application/json" -H "$(oauth2l header --json /secure/storage/cred.json androidPartner)" -H "X-GFE-SSL: yes" -d '{company_id: COMPANY_ID, device_payloads: [{certificate_payloads: [{certificate_signing_request: "CERTIFICATE_SIGNING_REQUEST"}]}]}' https://androidpartner.googleapis.com/v1/devices:batchUpload
Замените /secure/storage/cred.json путём к данным доступа, COMPANY_ID — ID компании Android Partner, CERTIFICATE_SIGNING_REQUEST — запросом сертификата в CBOR, полученным инструментом.
4. Тестирование и проверка
Проверка устройств: источник рекомендует подключать каждое выбранное устройство («каждые X устройств», X не задан) к внешней сети и запускать GTS AttestationRootHostTest. Успех означает правильную регистрацию и получение действительных сертификатов Google. Загружайте открытые ключи до поступления устройств на тестовую станцию.
Извлечение и загрузка должны быть надёжны на 100%: без загруженного открытого ключа устройство не получит ключи аттестации. Храните извлечённые данные с резервированием для целостности до загрузки.
Безопасность: источник описывает данные как зашифрованные ключом, доступным только серверу Google, и называет содержимое открытым ключом, не требующим высокосекретного хранения. Формулировка неоднозначна; см. редакционное предупреждение. Ограничивайте запись, чтобы злоумышленники не добавили поддельные ключи в заводскую базу. Ограничивайте и защищайте данные доступа Partner API для аутентификации загрузок.
5. Ошибки RKP API
Следующие ошибки загрузки CSR помогают диагностировать тесты RKP.
Ошибки конкретных операций
Нет разрешения пользователя для ID компании
Пользователь не имеет права загрузки для данной компании. Сообщение: CSR не загружен; {USER} не может загружать сведения устройств для {COMPANY_ID}. Создайте обращение или запросите доступ у TAM.
Код 7 (нет разрешения), HTTP 403.
Ключ уже существует
CSR с ранее загруженным открытым ключом отклоняется: CSR не загружен; открытый ключ устройства уже существует; вызовите BatchUpdate для изменения его данных. Код 6 (уже существует), HTTP 400. Для изменения сведений устройства, связанных с ключом, используйте API обновления.
Ключ отсутствует
Обновление отсутствующего ключа отклоняется: CSR не загружен; открытый ключ не найден; сначала вызовите BatchUpload. Код 5 (не найдено), HTTP 400.
Отсутствует версия CSR
CSR без версии отклоняется: CSR не загружен; отсутствует версия; проверьте поля. Код 3 (неверный аргумент), HTTP 400. Версия определяет, выполняется ли проверка изготовителя.
Изготовитель не найден
Из CSR нельзя извлечь изготовителя. Версия CSR 1 успешно загружается с предупреждением: изготовитель необязателен для VSR12, но обязателен начиная с VSR13; подготовьте заводские инструменты для будущих чипсетов. Это успех HTTP 200. Версия CSR 2 и выше не загружается: изготовитель обязателен с VSR13; код 3, HTTP 400.
Нет разрешения изготовителя
Пользователь не имеет прав для данного изготовителя. CSR 1 загружается с предупреждением: нет разрешения для {MANUFACTURER}, но CSR чипсетов VSR12 ещё принимаются; получите права для VSR13+. HTTP 200. CSR 2 и выше не загружается: отказано для {MANUFACTURER}; зарегистрируйте изготовителя и загрузите отчёт в Android Partner Approvals. Код 7, HTTP 403. При первой загрузке для нового/незарегистрированного изготовителя сначала подайте отчёт с его сведениями.
Повтор ключа в одном запросе
При многократной загрузке одного ключа: найден повтор открытого ключа устройства; ключ уже загружен. Код 3, HTTP 400.
Максимальное число CSR
Более 5000 CSR в запросе: достигнут предел; не загружайте более 5000 CSR на DevicePayload. Код 3, HTTP 400.
Не удаётся десериализовать CSR
Неверный CSR: не загружен; запрос подписи невозможно десериализовать при регистрации; проверьте повреждение данных. Код 3, HTTP 400.
Общие ошибки
Превышен срок: слишком много ключей, срок истёк. Сообщение: превышен срок; повторите с меньшим числом CSR; при повторении обратитесь к Google TAM. Код 4, HTTP 504.
Внутренняя ошибка: источник называет её некэшируемой и требующей разбора инженерами Google. Сообщение: внутренняя ошибка. Код 13.
Нет аутентификации: пользователь не аутентифицирован; см. настройку Partner API. Сообщение: нет аутентификации. Код 16, HTTP 401.
Ресурсы исчерпаны: например, превышена квота пользователя или закончилось место в файловой системе. Повторите позже. Код 8 (RESOURCE_EXHAUSTED), HTTP 429.
Сервис недоступен: вероятно временно; повторяйте с увеличением интервала. Сообщение: сервис недоступен. Код 14 (UNAVAILABLE), HTTP 503.
Операция прервана:
Операция прервана, обычно из-за параллельного доступа: сбоя проверки последовательности или отмены транзакции. Сообщение: операция прервана. Код 10 (ABORTED), HTTP 409.
Служба Google Cloud Platform отключена
Создание проекта GCP с аккаунтом партнёрского домена может дать сообщение с просьбой администратору включить сервис в G Suite Admin console. Источник запрещает создавать проекты таким аккаунтом: используйте корпоративную учётную запись. В Google Workspace попросите IT-администратора включить GCP для аккаунта.
6. Частые вопросы RKP
Загрузка и обновление сведений устройства
1. Почему HTTP 500 «внутренняя ошибка»? Некоторые реализации TEE неверно форматируют запросы, сервер не может разобрать данные и выдаёт 500. Повторите и сообщите о проблеме.
2. Почему CSR одного устройства различаются? Меняется ли открытый ключ? В Android 13 и ниже HAL шифрует часть CSR с данными открытого ключа. Случайность даёт разный шифротекст при каждом CSR HAL V1/V2. Открытый текст ключа должен оставаться одинаковым. По источнику, проверка требует участия серверной команды Google, способной расшифровать запрос.
3. Как посмотреть ключ открытым текстом? В Android 13 и ниже данные ключа шифруются в HAL. Источник говорит, что расшифровка доступна лишь серверу Google, не самим сотрудникам; на Android 13 посмотреть их нельзя. С Android 14 шифрование этих данных в HAL не требуется, что упрощает архитектуру и тесты. Речь о данных открытого ключа CSR, не о разрешении извлекать закрытый ключ.
4. Можно ли указать несерийное имя модели? Модель и изготовитель должны совпадать с регистрацией компании в Android Partner Approvals.
Загрузка CSR
1. Возникает ли ошибка при повреждённом CSR? Да, API возвращает документированные ошибки; сервер проверяет криптографические операции CSR.
2. Можно отменить или изменить неверный CSR?
Да. device_info_uploader автоматически обновляет устройство последними сведениями; повторно запустите его для обновления.
3. Что при повторной загрузке CSR? Обычный API загрузки возвращает ошибку уже загруженного ключа. API обновления меняет связанные метаданные, например manufacturer и model.
4. Есть ли предел загрузки? До 5,000 CSR на вызов API. Загрузчик автоматически делит вход на группы по 2,000: 100,000 CSR превращаются в 50 пакетов API по 2,000.
5. Какова задержка после загрузки? Источник утверждает, что задержки нет: RKP работает сразу после получения CSR сервером Google. Это утверждение источника, не измеренная гарантия сервиса.
6. Можно проверить зарегистрированные CSR на сервере Google? На дату руководства нет; Google рассматривала такую функцию. Обновление может показать отсутствие устройства, но внесённые изменения сохраняются. Или загрузите тот же CSR либо новый CSR того же устройства с device_info_uploader.py --no-update:
./device_info_uploader.py --credentials /secure/storage/cred.json --json-csr csrs.json --cache-token --company-id COMPANY_ID --no-update
Возвращается ответ вида:
"status": {
"code": 6,
"message": "This CSR was not uploaded. Device public key already exists. Please call BatchUpdate to modify an existing key's data."
}
Это означает, что CSR устройства уже загружен.
Тестирование
1. Как тестировать предсерийные устройства? Производственные устройства получают настоящие сертификаты аттестации, используемые Google для подписи запросов. Ранние прототипы не следует регистрировать как производственные. Установите is_test в true: ключ навсегда регистрируется как тестовый и не переводится в производственный обновлением сведений. Тестовый сертификат связан с тестовым корнем. Если нужны производственные сертификаты, например для GTS, можно изначально зарегистрировать устройство как производственное. Флаг загрузчика --is-test отмечает тестовое устройство.
Формулировка источника требует проверки: «Устройства с включённой безопасной загрузкой отмечать как тестовые; с выключенной — как производственные». Это противоречит ожидаемому доверию производства. Текст сохранён как неразрешённая ошибка черновика, не как указание выключать безопасную загрузку или регистрировать небезопасные устройства для производства. До необратимой регистрации уточните политику у уполномоченного владельца платформы.
2. Отличаются ли тесты userdebug от производства? Для незарегистрированных userdebug/eng сервис выдаёт тестовые сертификаты без загрузки ключей. Их тестовый корень пригоден для тестов, но не должен считаться доверенным для производственной аттестации. Далее источник говорит, что зарегистрированные устройства всегда получают производственные сертификаты независимо от сборки; эту фразу нужно согласовать с ранее описанной постоянной тестовой регистрацией, а не отменять её.
3. Можно загружать CSR устройств без требований отгрузки? Да, источник допускает внутренние и сторонние тесты.
4. Оставляет ли AttestationRootHostTest следы? Да, но очистка пользовательских данных удаляет все следы этого теста. Она удаляет и пользовательские данные: сначала создайте копию.
5. Минимальные требования? Нужна ли SIM из процедуры GTS? Источник перечисляет только соединение с сервером Google и уже загруженный ключ устройства; SIM в минимальном перечне нет.
6. Провалит ли RKP GTS устройство, выпущенное с Android 12 и обновлённое до 13? Источник отвечает нет: требование относится к выпуску с Android 13. Точная логика приведена ниже псевдокодом.
bool is_rkp_supported() { # not supported on CN-GMS devices if
has_feature("cn.google.services") AND has_package("com.google.android.gms"):
return false # supported on T+ with VSR S+ if ro.product.first_api_level >= 33
AND ro.vendor.api_level >= 31: return true # otherwise unsupported return
false}
7. Почему падает testFallback или AttestationRootHostTest.testFallbackKey? Тесты проверяют возврат Keymint к заводским ключам при отсутствии удалённых. Без локального ключа аттестации keystore не создаст аттестованный ключ подписи: нет резервного ключа для подтверждения. Ошибка ожидаема; обеспечьте локальный ключ и повторите.
8. Почему все тесты RKP GTS завершаются ошибкой?
Частая причина — отсутствие RemoteProvisioner APK в образе. По источнику, общий AOSP-образ его не содержит; в GMS-устройства его нужно включать явно, поскольку RKP является требованием GMS, а не CDD. Установку проверяет AttestationRootTest.testRemoteProvisionerInstalled. Если APK отсутствует, добавьте его в образ.
9. Что означает com.android.remoteprovisioner.RemoteProvisioningException: HTTP error status encountered: 444?
Согласно определению RemoteProvisioningException в источнике, 444 означает отсутствие регистрации устройства на сервере Google.
