Android Remote Key Provisioning (Software)
Software implementation of the Android RKP protocol that generates
AuthenticatedRequest CSRs, communicates with Google's production RKP server,
and exports keybox.xml for key attestation.
Overview
Android devices with KeyMint 2.0+ use Remote Key Provisioning to obtain attestation certificates from Google. The on-device flow requires a Trusted Execution Environment (TEE) to derive cryptographic keys and sign provisioning requests.
This tool replicates that flow entirely in software, given a device's 32-byte CDI_Leaf seed.
Architecture
+-----------+
| RKP Server| (Google production)
+-----+-----+
|
fetchEekChain / signCertificates
|
+-----------------------------+-----------------------------+
| rkp_sw.py |
| |
| CDI_Leaf Seed ─── Signing Key ─── DICE Chain |
| | (Ed25519 or P-256) | |
| | ECDH-ES + HKDF ─── AES-256-GCM |
| | | |
| v v |
| COSE_Sign1 COSE_Encrypt0 (ProtectedData) |
| | | |
| +-------+--------+ |
| | |
| AuthenticatedRequest (CBOR) |
+-----------------------------------------------------------+Requirements
- Python 3.10+
- cbor2
- cryptography >= 41.0
pip install cbor2 cryptographyConfiguration
Copy template.conf to a private config file and fill in device-specific
values:
cp template.conf device_prop.confThe config uses INI format with [device] and [fingerprint] sections.
See template.conf for all supported fields. Private config files
(device_prop.conf) are excluded from version control via .gitignore.
Usage
Show device and key information
python3 rkp_sw.py info --seed <64-hex> --config device_prop.conf
python3 rkp_sw.py info --seed <64-hex> --curve p256 --config device_prop.confProvision attestation keys
Generate EC P-256 keypairs, build a CSR, and submit to Google's RKP server:
python3 rkp_sw.py provision --seed <64-hex> --config device_prop.conf
python3 rkp_sw.py provision --seed <64-hex> --curve p256 --config device_prop.conf -n 2The --curve flag selects the DICE chain signing key type: ed25519
(default) or p256.
Export keybox.xml
Provision a key and export the result as an Android keybox.xml:
python3 rkp_sw.py keybox --seed <64-hex> --config device_prop.conf -o keybox.xmlVerify a CSR
python3 rkp_sw.py verify csr_output.cborProtocol
The tool implements the full generateCertificateRequestV2 protocol:
- EEK fetch —
POST :fetchEekChainreturns the server's Endpoint Encryption Key chain and a challenge nonce. - CSR build — Constructs an
AuthenticatedRequestcontaining:DeviceInfo(CBOR map from config)DiceCertChain(Degenerate DICE: UDS = CDI_Leaf, self-signed)ProtectedData(COSE_Encrypt0 with ECDH-ES + AES-256-GCM)SignedData(COSE_Sign1 over challenge + payload)
- CSR submit —
POST :signCertificatesreturns X.509 certificate chains signed by Google's attestation root.
References
| Specification | Use |
|---|---|
| RFC 9052 | COSE_Sign1, COSE_Encrypt0 structures |
| RFC 9053 | EdDSA, ES256, ECDH-ES, AES-256-GCM algorithm identifiers |
| RFC 8392 | CWT claims (issuer, subject) |
| Open DICE | DICE certificate chain profile |
| Android RKP AIDL | AuthenticatedRequest CDDL schema |
License
Copyright 2025 mhmrdd <1@mhmrdd.me>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0