В этом руководстве рассказывается, как регистраторы верификаторов – поставщики услуг по подтверждению личности, агрегаторы и платформы, которые проверяют пользователей от имени нескольких клиентов (конечных проверяющих сторон), – настраивают свой центр сертификации, кодируют метаданные CBOR и интегрируют Digital Credentials API.
Выберите способ Полагающаяся сторона, регистратор или личная встреча
Как работает интеграция с регистратором верификаторов
Как регистратор верификаторов, вы действуете как собственный центр сертификации, подписывая запросы на идентификацию для управляемых вами конечных сторон, полагающихся на сертификаты. Выберите шаг, чтобы перейти к подробным инструкциям по его выполнению:
Шаг А. Настройте профиль сертификата ЦС и метаданные CBOR
1. Профиль сертификата
Запросы должны быть подписаны стандартными сертификатами конечного субъекта X.509 v3 (связанными с вашим зарегистрированным корневым центром сертификации для тестовой или рабочей среды), созданными с помощью P-256 / ECDSA и содержащими специальное расширение Google:
- Идентификатор объекта специального расширения:
1.3.6.1.4.1.11129.10.1 - Критичность. Некритическая.
- Содержимое. Хеш SHA-256 для
RelyingPartyMetadataBytes, закодированный в ASN.1OCTET STRING. - Тема (различающееся имя). Должна быть глобально уникальной для каждого дочернего конечного проверяющего агента, для которого вы подписываете сертификат.
Применяется только к сертификатам конечных субъектов. Эти требования к специальным расширениям и субъектам применяются только к сертификатам конечных субъектов, представляющим ваши дочерние конечные проверяющие стороны. Для корневых ЦС тестовой и рабочей среды, а также для любых промежуточных ЦС не требуется специальное расширение OID Google и не нужно указывать субъект, относящийся к конечной проверяющей стороне.

2. Схема метаданных (CBOR)
Метаданные для каждой конечной проверяющей стороны (и необязательный брендинг агрегатора) должны быть закодированы в формате CBOR:
; in CDDL for CBOR encoding
; schemaVersion = "v1"
RelyingPartyMetadataBytes = #6.24(bstr .cbor RelyingPartyMetadata)
RelyingPartyMetadata = {
"schema_version": tstr,
"display": DisplayInfo,
"aggregator_info": DisplayInfo ; Optional: include to show your branding alongside the RP
}
DisplayInfo = {
"display_name": tstr,
"logo_uri": tstr, ; See brand guidelines link in following paragraph
"privacy_policy_uri": tstr
}
logo_uri должен соответствовать правилам фирменного оформления Google Кошелька.
3. Интеграция метаданных OpenID4VP
При форматировании подписанного запроса учетных данных OpenID4VP на шаге Б включите закодированный по стандарту Base64URL RelyingPartyMetadataBytes в поле gw_rp_metadata_bytes внутри объекта client_metadata, а также цепочку сертификатов конечного субъекта конечной проверяющей стороны в заголовок JWS x5c.
Поддерживаемые форматы, учетные данные и функции
Google Кошелек поддерживает цифровые удостоверения личности на основе ISO mdoc, которые передаются по протоколу OpenID4VP (версия 1.0). Они доступны на устройствах с Android 9 (уровень API 28) и более поздними версиями, а также в поддерживаемых браузерах.
Поддерживаемые учетные данные и атрибуты
Посмотрите, какие идентификаторы doctype_value (цифровое водительское удостоверение, цифровое удостоверение личности, удостоверение личности с фотографией) и пути к атрибутам можно запрашивать у Google Кошелька.
Поддерживаемые эмитенты и сертификаты IACA
Скачайте официальные корневые сертификаты IACA для штатов США, международных эмитентов и эмитента Sandbox Utopia, чтобы подтвердить issuerAuth.
Шаг 2. Отформатируйте и подпишите запрос (на стороне сервера)
Чтобы запросить учетные данные из любого кошелька, необходимо отформатировать запрос с помощью OpenID4VP на сервере. Вы можете запросить определенные учетные данные или несколько учетных данных в одном объекте dcql_query.
Пример запроса JSON
Ниже приведен пример запроса mdoc requestJson для получения удостоверения личности из любого кошелька на устройстве Android или в интернете.
{
"requests" : [
{
"protocol": "openid4vp-v1-signed",
"data": {<signed_credential_request>} // This is an object, shouldn't be a string.
}
]
}
Запрашивать шифрование
client_metadata содержит открытый ключ шифрования для каждого запроса.
Вам нужно будет хранить закрытые ключи для каждого запроса и использовать их для аутентификации и авторизации токена, полученного из приложения кошелька.
Интегрированные метаданные OpenID4VP
При форматировании запроса учетных данных необходимо включить поле gw_rp_metadata_bytes в объект client_metadata (как показано в примере кода запроса ниже). Это поле содержит метаданные доверяющей стороны, закодированные в Base64URL и необходимые Google Кошельку для подтверждения вашей личности и показа вашего брендинга пользователю.
Полезная нагрузка запроса учетных данных
Параметр credential_request в requestJson содержит следующие поля.
Определенные учетные данные
{
"response_type": "vp_token",
"response_mode": "dc_api.jwt", // change this to dc_api if you want to demo with a non encrypted response.
"nonce": "1234",
"dcql_query": {
"credentials": [
{
"id": "cred1",
"format": "mso_mdoc",
"meta": {
// Use org.iso.18013.5.1.mDL for mDL,
// com.google.wallet.idcard.1 for ID pass, or
// org.iso.23220.photoid.1 for ID pass (using photo ID document type)
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.18013.5.1",
"age_over_18"
],
"intent_to_retain": false
}
]
}
]
},
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
"kty": "EC",
"crv": "P-256",
"x": "pDe667JupOe9pXc8xQyf_H03jsQu24r5qXI25x_n1Zs",
"y": "w-g0OrRBN7WFLX3zsngfCWD3zfor5-NLHxJPmzsSvqQ",
"use": "enc",
"kid" : "1", // This is required
"alg" : "ECDH-ES", // This is required
}
]
},
"vp_formats_supported": {
"mso_mdoc": {
"deviceauth_alg_values": [
-7
],
"issuerauth_alg_values": [
-7
]
}
},
"gw_rp_metadata_bytes": "<base64url encoded metadata string>"
}
}
Любые подходящие учетные данные
Ниже приведен пример запроса для цифрового водительского удостоверения, цифрового удостоверения личности и цифрового удостоверения личности (с использованием типа документа "Удостоверение личности с фотографией"). Пользователь может продолжить с любым из них.
{
"response_type": "vp_token",
"response_mode": "dc_api.jwt", // change this to dc_api if you want to demo with a non encrypted response.
"nonce": "1234",
"dcql_query": {
"credentials": [
{
"id": "mdl-request",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.18013.5.1",
"age_over_18"
],
"intent_to_retain": false
}
]
},
{ // Credential type 2: ID pass
"id": "id_pass-request",
"format": "mso_mdoc",
"meta": {
"doctype_value": "com.google.wallet.idcard.1"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.18013.5.1",
"age_over_18"
],
"intent_to_retain": false
}
]
},
{ // Credential type 3: ID pass (using photo ID document type)
"id": "photo_id-request",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.23220.photoid.1"
},
"claims": [
{
"path": [
"org.iso.23220.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.23220.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.23220.1",
"age_over_18"
],
"intent_to_retain": false
}
]
}
]
credential_sets : [
{
"options": [
[ "mdl-request" ],
[ "id_pass-request" ],
[ "photo_id-request" ]
]
}
]
},
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
"kty": "EC",
"crv": "P-256",
"x": "pDe667JupOe9pXc8xQyf_H03jsQu24r5qXI25x_n1Zs",
"y": "w-g0OrRBN7WFLX3zsngfCWD3zfor5-NLHxJPmzsSvqQ",
"use": "enc",
"kid" : "1", // This is required
"alg" : "ECDH-ES", // This is required
}
]
},
"vp_formats_supported": {
"mso_mdoc": {
"deviceauth_alg_values": [
-7
],
"issuerauth_alg_values": [
-7
]
}
},
"gw_rp_metadata_bytes": "<base64url encoded metadata string>"
}
}
Вы можете запросить любое количество поддерживаемых атрибутов из любого удостоверения личности, сохраненного в Google Кошельке.
Подписанные запросы
Подписанные запросы (запросы авторизации, защищенные JWT) включают запрос на подтверждение в криптографически подписанный веб-токен JSON (JWT). При этом используется ваша инфраструктура PKI, что обеспечивает целостность запроса и подтверждает вашу личность для Google Кошелька.
Требования
Прежде чем вносить изменения в код для подписанных запросов, убедитесь, что у вас есть:
- Закрытый ключ. Вам нужен закрытый ключ (например, Elliptic Curve
ES256), чтобы подписывать запросы, управляемые на вашем сервере. Для тестирования в изолированной среде в качестве полагающейся стороны используйте закрытый ключ для тестирования в изолированной среде. - Сертификат. Вам нужен стандартный сертификат X.509, полученный из вашей пары ключей.
- Регистрация. Убедитесь, что Google Кошелек доверяет вашему общедоступному сертификату (или корневому центру сертификации для регистраторов верификаторов).
Логика создания запросов
При создании и подписании запроса OpenID4VP обратите особое внимание на то, какой формат кодировки ожидается для каждого поля. Если вы перепутаете base64 и base64url или заполнение (=), то проверка подписи или источника не будет выполнена.
| Поле | Требуемая кодировка / формат | Символы и отступы |
|---|---|---|
client_id (x509_hash:<hash>) |
base64url без заполнения. | Используется алфавит, безопасный для URL (-, _); удалите конечные символы =. |
expected_origins (android:apk-key-hash:<hash>) |
Стандартный Base64 без заполнения | Используется стандартный алфавит (+, /); удаляется завершающий символ =. |
expected_origins (https://...) |
URL в нижнем регистре без косой черты в конце. | Пример: https://example.com (без / в конце). |
Заголовок JWS x5c |
Стандартная кодировка Base64 с заполнением. | Используется стандартный алфавит (+, /); сохраняется заполнение = в конце. |
Чтобы создать запрос, используйте закрытый ключ и упакуйте полезную нагрузку в JWS:
def construct_openid4vp_request(
doctypes: list[str],
requested_fields: list[dict],
nonce_base64: str,
jwe_encryption_public_jwk: jwk.JWK,
is_zkp_request: bool,
is_signed_request: bool,
state: dict,
origin: str
) -> dict:
# ... [Existing logic to build 'presentation_definition' and basic 'request_payload'] ...
# ------------------------------------------------------------------
# SIGNED REQUEST IMPLEMENTATION (JAR)
# ------------------------------------------------------------------
if is_signed_request:
try:
# 1. Load the Verifier's Certificate
# We must load the PEM string into a cryptography x509 object
verifier_cert_obj = x509.load_pem_x509_certificate(
CERTIFICATE.encode('utf-8'),
backend=default_backend()
)
# 2. Calculate Client ID (x509_hash)
# We calculate the SHA-256 hash of the DER-encoded certificate.
cert_der = verifier_cert_obj.public_bytes(serialization.Encoding.DER)
verifier_fingerprint_bytes = hashlib.sha256(cert_der).digest()
# Important: Use URL-safe Base64 (base64url: '-', '_') without padding ('=') for client_id
verifier_fingerprint_b64 = base64.urlsafe_b64encode(verifier_fingerprint_bytes).decode('utf-8').rstrip("=")
# Format the client_id as required by the spec
client_id = f'x509_hash:{verifier_fingerprint_b64}'
# 3. Update Request Payload with JAR specific fields
request_payload["client_id"] = client_id
# Explicitly set expected origins to prevent relay attacks
# Important: Use standard Base64 (not URL-safe) without padding for android:apk-key-hash:
# origin = f"android:apk-key-hash:{base64.b64encode(apk_cert_hash).decode('utf-8').rstrip('=')}"
# Format for web origin (lowercase URL without trailing slash): origin = "https://example.com"
if origin:
request_payload["expected_origins"] = [origin]
# 4. Create Signed JWT (JWS)
# Load the signing private key
signing_key = jwk.JWK.from_pem(PRIVATE_KEY.encode('utf-8'))
# Initialize JWS with the JSON payload
jws_token = jws.JWS(json.dumps(request_payload).encode('utf-8'))
# Construct the JOSE Header
# 'x5c' (X.509 Certificate Chain) is critical: it allows the wallet
# to validate your key against the one registered in the console.
# Important: Use standard Base64 ('+', '/') WITH padding ('=') for x5c
x5c_value = base64.b64encode(cert_der).decode('utf-8')
protected_header = {
"alg": "ES256", # Algorithm (e.g., ES256 or RS256)
"typ": "oauth-authz-req+jwt", # Standard type for JAR
"kid": "1", # Key ID
"x5c": [x5c_value] # Embed the certificate
}
# Sign the token
jws_token.add_signature(
key=signing_key,
alg=None,
protected=json_encode(protected_header)
)
# 5. Return the Request Object
# Instead of returning the raw JSON, we return the signed JWT string
# under the 'request' key.
return {"request": jws_token.serialize(compact=True)}
except Exception as e:
print(f"Error signing OpenID4VP request: {e}")
return None
# ... [Fallback for unsigned requests] ...
return request_payload
Шаг 3. Активируйте API (на стороне клиента)
Весь запрос к API должен генерироваться на стороне сервера. В зависимости от платформы передайте сгенерированный JSON в API платформы.
В приложении (Android)
Чтобы запросить удостоверение личности из приложений Android, выполните следующие действия:
Обновить зависимости
В файле build.gradle проекта обновите зависимости, чтобы использовать Менеджер учетных данных (бета-версия):
dependencies {
implementation("androidx.credentials:credentials:1.5.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.5.0-beta01")
}
Как настроить Менеджер учетных данных
Чтобы настроить и инициализировать объект CredentialManager, добавьте логику, аналогичную следующей:
// Use your app or activity context to instantiate a client instance of CredentialManager.
val credentialManager = CredentialManager.create(context)
Запросить атрибуты идентификации
Вместо того чтобы указывать отдельные параметры для запросов идентификации, приложение предоставляет их все вместе в виде строки JSON в CredentialOption.
Менеджер учетных данных передает эту строку JSON доступным цифровым кошелькам, не проверяя ее содержимое. Каждый кошелек отвечает за:
- Анализ строки JSON для понимания запроса идентификации.
- Определяет, какие из сохраненных учетных данных соответствуют запросу.
Мы рекомендуем партнерам создавать запросы на сервере даже для интеграции приложений Android.
В качестве request в вызове функции GetDigitalCredentialOption() используйте requestJson из раздела Форматирование и подпись запроса.
// The request in the JSON format to conform with
// the JSON-ified Digital Credentials API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
GetDigitalCredentialOption(requestJson = requestJson)
// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
listOf(digitalCredentialOption)
)
coroutineScope.launch {
try {
val result = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
verifyResult(result)
} catch (e : GetCredentialException) {
handleFailure(e)
}
}
Обработка ответа с учетными данными
Получив ответ от кошелька, проверьте, является ли он успешным и содержит ли ответ credentialJson:
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson) // make a server call to validate the response
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
}
// Handle failure.
fun handleFailure(e: GetCredentialException) {
when (e) {
is GetCredentialCancellationException -> {
// The user intentionally canceled the operation and chose not
// to share the credential.
}
is GetCredentialInterruptedException -> {
// Retry-able error. Consider retrying the call.
}
is NoCredentialException -> {
// No credential was available.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}
Ответ credentialJson содержит зашифрованный токен identityToken (JWT), определенный W3C. За создание этого ответа отвечает приложение "Кошелек".
Пример:
{
"protocol" : "openid4vp-v1-signed",
"data" : {
<encrypted_response>
}
}
Передайте этот ответ на свой сервер, чтобы проверить его подлинность. Подробнее о том, как расшифровать и проверить ответ…
Веб
Чтобы запросить удостоверение личности с помощью Digital Credentials API в Chrome или другом поддерживаемом браузере, выполните следующий запрос:
const credentialResponse = await navigator.credentials.get({
digital : {
requests : [
{
protocol: "openid4vp-v1-signed",
data: {<credential_request>} // This is an object, shouldn't be a string.
}
]
}
})
Отправьте ответ от этого API обратно на свой сервер, чтобы проверить ответ учетных данных.
Шаг 4. Расшифруйте и проверьте ответ (на стороне сервера)
Когда кошелек вернет зашифрованный токен identityToken (JWT), вы должны выполнить строгую проверку на стороне сервера, прежде чем доверять данным.
Расшифровка ответа
Расшифруйте JWE с помощью закрытого ключа, соответствующего открытому ключу, который был отправлен в поле client_metadata запроса. Это дает vp_token.
Пример на Python:
from jwcrypto import jwe, jwk
# Retrieve the Private Key from Datastore
reader_private_jwk = jwk.JWK.from_json(jwe_private_key_json_str)
# Save public key thumbprint for session transcript
encryption_public_jwk_thumbprint = reader_private_jwk.thumbprint()
# Decrypt the JWE encrypted response from Google Wallet
jwe_object = jwe.JWE()
jwe_object.deserialize(encrypted_jwe_response_from_wallet)
jwe_object.decrypt(reader_private_jwk)
decrypted_payload_bytes = jwe_object.payload
decrypted_data = json.loads(decrypted_payload_bytes)
decrypted_data возвращает объект vp_token JSON, содержащий учетные данные:
{
"vp_token":
{
"cred1": ["<base64UrlNoPadding_encoded_credential>"] // This applies to OpenID4VP 1.0 spec.
}
}
Восстановление SessionTranscript и проверка DeviceResponse
- Создайте SessionTranscript из ISO/IEC 18013-5:2021 со структурой Handover для Android или веб-страниц:
SessionTranscript = [
null, // DeviceEngagementBytes not available
null, // EReaderKeyBytes not available
[
"OpenID4VPDCAPIHandover",
AndroidHandoverDataBytes // BrowserHandoverDataBytes for Web
]
]
Для передачи как на Android, так и на веб-странице используйте тот же nonce, который вы использовали для создания credential_request.
Android Handover
AndroidHandoverData = [ origin, // "android:apk-key-hash:<base64SHA256_ofAppSigningCert>", nonce, // nonce that was used to generate credential request, encryption_public_jwk_thumbprint, // Encryption public key (JWK) Thumbprint ] AndroidHandoverDataBytes = hashlib.sha256(cbor2.dumps(AndroidHandoverData)).digest()
Передача браузера
BrowserHandoverData =[ origin, // Origin URL nonce, // nonce that was used to generate credential request encryption_public_jwk_thumbprint, // Encryption public key (JWK) Thumbprint ] BrowserHandoverDataBytes = hashlib.sha256(cbor2.dumps(BrowserHandoverData)).digest()
При использовании SessionTranscript ответ устройства должен быть проверен в соответствии с пунктом 9 стандарта ISO/IEC 18013-5:2021.
Проверка состоит из четырех этапов:
- Проверьте сертификат издателя. Извлеките цепочку сертификатов подписи издателя из
issuerAuthи проверьте ее на соответствие доверенным корневым сертификатам IACA. Ознакомьтесь со списком поддерживаемых эмитентов и сертификатов IACA (и добавьте сертификат Utopia Sandbox, если вы тестируете удостоверение в изолированной среде). - Проверка подписи MSO (ISO/IEC 18013-5, раздел 9.1.2).
- Рассчитайте и проверьте
ValueDigestsдля элементов данных (ISO/IEC 18013-5, раздел 9.1.2). - Проверьте подпись
deviceSignature(ISO/IEC 18013-5, раздел 9.1.3).
{
"version": "1.0",
"documents": [
{
"docType": "org.iso.18013.5.1.mDL",
"issuerSigned": {
"nameSpaces": {...}, // contains data elements
"issuerAuth": [...] // COSE_Sign1 w/ issuer PK, mso + sig
},
"deviceSigned": {
"nameSpaces": 24(<< {} >>), // empty
"deviceAuth": {
"deviceSignature": [...] // COSE_Sign1 w/ device signature
}
}
}
],
"status": 0
}
Шаг 5 (необязательно). Подтверждение возраста с сохранением конфиденциальности (ZKP)
Чтобы поддерживать доказательства с нулевым разглашением (например, подтверждать, что пользователю больше 18 лет, не видя его точную дату рождения), измените формат запроса на mso_mdoc_zk и укажите необходимую конфигурацию zk_system_type.
Общие сведения о ZKP и его возможностях приведены в разделе часто задаваемых вопросов.
...
"dcql_query": {
"credentials": [{
"id": "cred1",
"format": "mso_mdoc_zk",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
"zk_system_type": [
{
"system": "longfellow-libzk-v1",
"circuit_hash": "f88a39e561ec0be02bb3dfe38fb609ad154e98decbbe632887d850fc612fea6f", // This will differ if you need more than 1 attribute.
"num_attributes": 1, // number of attributes (in claims) this has can support
"version": 5,
"block_enc_hash": 4096,
"block_enc_sig": 2945,
}
{
"system": "longfellow-libzk-v1",
"circuit_hash": "137e5a75ce72735a37c8a72da1a8a0a5df8d13365c2ae3d2c2bd6a0e7197c7c6", // This will differ if you need more than 1 attribute.
"num_attributes": 1, // number of attributes (in claims) this has can support
"version": 6,
"block_enc_hash": 4096,
"block_enc_sig": 2945,
}
],
"verifier_message": "challenge"
},
"claims": [{
...
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
...
Вы получите от кошелька зашифрованное доказательство с нулевым разглашением. Вы можете проверить это подтверждение по сертификатам IACA эмитента, используя библиотеку Google longfellow-zk.
verifier-service содержит готовый к развертыванию сервер на основе Docker, который позволяет проверять ответ по сертификатам IACA эмитента.
Вы можете изменить файл certs.pem, чтобы управлять сертификатами издателя IACA, которым вы хотите доверять.
SDK, примеры реализации и поддержка
Чтобы ускорить реализацию, используйте наши библиотеки с открытым исходным кодом, эталонный сервер и инструмент проверки веб-страниц.
| Ресурс / библиотека | Что он дает | Ссылка |
|---|---|---|
| Identity Verifiers Reference Implementation | Пример сервера и клиента, демонстрирующий создание запроса OpenID4VP, подпись JWS, расшифровку JWE и проверку ответа mdoc. | Хранилище GitHub |
| Multipaz SDK | Библиотека с открытым исходным кодом (OpenWallet Foundation), включая DeviceResponseParser для декодирования CBOR, реконструкцию SessionTranscript и проверку подписи ISO/IEC 18013-5/7. |
openwallet-foundation/multipaz |
| Библиотека Longfellow ZKP и сервис Verifier | Библиотека с открытым исходным кодом и сервер на основе Docker для проверки возраста и атрибутов с помощью доказательства с нулевым разглашением (mso_mdoc_zk). |
google/longfellow-zk |
| Интерактивный инструмент проверки сайтов | Размещенный в интернете верификатор для тестирования запросов W3C Digital Credentials API / OpenID4VP к Google Кошельку. | verifier.multipaz.org |
| Спецификация OpenID4VP 1.0 | Официальная спецификация протокола OpenID for Verifiable Presentations 1.0. | Спецификация OpenID4VP |
| Часто задаваемые вопросы и поддержка разработчиков | Ответы на часто задаваемые вопросы о технической интеграции. Если вам нужна помощь с отладкой, напишите на адрес wallet-identity-rp-support@google.com. |
Часто задаваемые вопросы о технической интеграции |