verified-email
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFundamentals
基础
- Overview of Digital Credentials: Learn about cryptographically verifiable documents and the role of Credential Manager.
- Glossary : Definitions for ,
dcql_query, andUserInfoCredential.GetDigitalCredentialOption
- 数字凭证概述:了解加密可验证文档以及Credential Manager的作用。
- 术语表:、
dcql_query和UserInfoCredential的定义。GetDigitalCredentialOption
Standards & Examples
标准与示例
- OpenID4VP Standard: The specification used to create digital credentials requests.
- Digital Credentials Demo: Example requests and cross-platform testing tool.
- W3C Verifiable Credentials: The data model for cryptographically secured claims.
- SD-JWT: Selective Disclosure JSON Web Token format used for responses.
- mdoc: ISO/IEC 18013-5 standard for mobile documents.
- OpenID4VP标准:用于创建数字凭证请求的规范。
- 数字凭证演示:示例请求和跨平台测试工具。
- W3C可验证凭证:加密安全声明的数据模型。
- SD-JWT:用于响应的选择性披露JSON Web Token格式。
- mdoc:移动文档的ISO/IEC 18013-5标准。
Requirements
要求
- SDK Version: Minimum SDK 28 (Android 9) is required.
- GMS Version: Google Play services version 25.49.x or higher.
- SDK版本:最低要求SDK 28(Android 9)。
- GMS版本:Google Play服务版本25.49.x或更高。
Use Cases
使用场景
Email verification is applicable for the following use cases:
- Account Creation/Sign-up: Remove friction by skipping manual email verification.
- Account Recovery: Securely verify email ownership during recovery flows.
- Re-authentication: Versatile verification for high-risk actions, independent of the initial sign-in method.
邮箱验证适用于以下场景:
- 账户创建/注册:跳过手动邮箱验证,减少流程繁琐度。
- 账户恢复:在恢复流程中安全验证邮箱所有权。
- 重新认证:针对高风险操作的通用验证方式,与初始登录方法无关。
Limitations & Nuances
限制与细节
- Workspace Accounts: Google does not issue verifiable credentials for Google Workspace Accounts.
- Freshness: For non-@gmail.com addresses, Google verifies the email at account creation but there is no freshness claim; implement an additional challenge like an OTP.
- 工作区账户:Google不为Google Workspace账户颁发可验证凭证。
- 时效性:对于非@gmail.com地址,Google仅在账户创建时验证邮箱,但不提供时效性声明;需实现额外验证环节,如OTP。
Scope & Pre-requisites
范围与前提条件
Crucial : This skill focuses exclusively on the Android client-side
integration . It does not implement the app's server-side cryptographic
validation logic. Server-side validation of the returned credential is required
for security and must be implemented in your backend.
关键提示:本技能仅专注于Android客户端集成,不实现应用服务器端的加密验证逻辑。为保障安全,必须在后端实现对返回凭证的服务器端验证。
Codebase exploration for Use Cases
用例代码库探索
Get started with the following queries in project source code to find relevant
screens with different use cases to implement verified email:
SignUpScreen"Email address""Recover Account""Account Recovery""Forgot password?""Delete Account"
通过以下项目源代码查询,可找到实现验证邮箱的相关用例界面:
SignUpScreen"Email address""Recover Account""Account Recovery""Forgot password?""Delete Account"
Identifying Integration Points
识别集成点
To implement this feature effectively, you must first locate the relevant
flows in your codebase. To initiate, start with the following strategies to
cater to different use cases using verified email:
要有效实现此功能,需先在代码库中定位相关流程。可通过以下策略针对不同验证邮箱用例展开:
1. Search for Navigation Routes
1. 搜索导航路由
If your app uses Navigation, search for routes or destinations related
to authentication:
Look for:
- Keywords : ,
signup,registration,create_account,forgot_password,recovery.verify_email - Code Pattern : Search for or
NavHostdestinations using these strings.composable
如果应用使用Navigation组件,搜索与认证相关的路由或目标页面:
查找:
- 关键词:、
signup、registration、create_account、forgot_password、recovery。verify_email - 代码模式:搜索包含上述字符串的或
NavHost目标页面。composable
2. Locate Authentication ViewModels
2. 定位认证ViewModel
Find the business logic handling user attributes and account creation, account
recovery:
- Keywords : ,
SignUpViewModel,AuthViewModel.RegistrationRepository - Code Pattern : Look for methods like ,
onCrea teAccount, oronRecoverAccount.validateEmail
查找处理用户属性、账户创建及账户恢复的业务逻辑:
- 关键词:、
SignUpViewModel、AuthViewModel。RegistrationRepository - 代码模式:查找、
onCreateAccount或onRecoverAccount等方法。validateEmail
3. Find instances of reauthentication for sensitive actions
3. 查找敏感操作的重新认证实例
For reauthentication use cases, find areas where users perform sensitive
actions:
- Keywords : ,
ChangePassword,UpdatePayment,DeleteAccount,UpdateDetailsEditUserDetails
对于重新认证用例,定位用户执行敏感操作的区域:
- 关键词:、
ChangePassword、UpdatePayment、DeleteAccount、UpdateDetailsEditUserDetails
Important pointers for Implementation
实现重要提示
- Construct a Digital Credential Request and present it to the user.
- Make sure to follow the request JSON structure as mentioned in documentation.
- While presenting the request to the user, check if result credential is DigitalCredential and credential.credentialJson as responseJsonString
- Parse the response from the client.
- Offer a passkey creation option if one is not already present.
- Assume a local to parse raw SD-JWT and return a
SdJwtParser.JSONObject - Use a data class to store the parsed name and email.
VerifiedUserInfo - Leave a TODO for developers to handle the app's server-side validation and parsing.
- Direct users to the home screen after API call success and show a snackbar with user details for reference purpose only.
This guide describes how to implement verified email retrieval using the
Digital Credentials Verifier API through an OpenID for Verifiable
Presentations (OpenID4VP) request.
- 构建数字凭证请求并呈现给用户。
- 确保遵循文档中提到的请求JSON结构。
- 向用户呈现请求时,检查返回的凭证是否为DigitalCredential,并将作为
credential.credentialJson。responseJsonString - 解析客户端返回的响应。
- 若尚未存在密钥,提供创建密钥的选项。
- 假设存在本地用于解析原始SD-JWT并返回
SdJwtParser。JSONObject - 使用数据类存储解析后的姓名和邮箱。
VerifiedUserInfo - 为开发者留下TODO注释,提示处理应用的服务器端验证与解析逻辑。
- API调用成功后将用户引导至首页,并显示包含用户详情的 snackbar(仅作参考用途)。
本指南介绍如何通过OpenID for Verifiable Presentations (OpenID4VP)请求,利用数字凭证验证器API实现验证邮箱获取。
Add dependencies
添加依赖
In your app's file, add the following dependencies for Credential
Manager:
build.gradle在应用的文件中,添加以下Credential Manager相关依赖:
build.gradleKotlin
Kotlin
kotlin
dependencies {
implementation("androidx.credentials:credentials:1.7.0-alpha02")
implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha02")
}kotlin
dependencies {
implementation("androidx.credentials:credentials:1.7.0-alpha02")
implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha02")
}Groovy
Groovy
groovy
dependencies {
implementation "androidx.credentials:credentials:1.7.0-alpha02"
implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02"
}groovy
dependencies {
implementation "androidx.credentials:credentials:1.7.0-alpha02"
implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02"
}Initialize Credential Manager
初始化Credential Manager
Use your app or activity context to create a object.
CredentialManager// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)使用应用或活动上下文创建对象。
CredentialManager// 使用应用或活动上下文实例化CredentialManager客户端
private val credentialManager = CredentialManager.create(context)Construct the Digital Credential request
构建数字凭证请求
To request a verified email, construct a
containing a . This option requires a
string formatted as an OpenID for Verifiable Presentations
(OpenID4VP) request.
GetCredentialRequestGetDigitalCredentialOptionrequestJsonThe OpenID4VP request JSON must follow a specific structure. The current
providers support a JSON structure with an outer wrapper.
"digital": {"requests": [...]} val nonce = generateSecureRandomNonce()
// This request follows the OpenID4VP spec
val openId4vpRequest = """
{
"requests": [
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "$nonce",
"dcql_query": {
"credentials": [
{
"id": "user_info_query",
"format": "dc+sd-jwt",
"meta": {
"vct_values": ["UserInfoCredential"]
},
"claims": [
{"path": ["email"]},
{"path": ["name"]},
{"path": ["given_name"]},
{"path": ["family_name"]},
{"path": ["picture"]},
{"path": ["hd"]},
{"path": ["email_verified"]}
]
}
]
}
}
}
]
}
"""
val getDigitalCredentialOption = GetDigitalCredentialOption(requestJson = openId4vpRequest)
val request = GetCredentialRequest(listOf(getDigitalCredentialOption))The request contains the following key information:
-
DCQL query : Thespecifies the credential type and the claims being requested (
dcql_query). You can request other claims to determine the level of verification. A few possible claims are as follows:email_verified- : In the response, this is a Boolean that indicates whether the email is verified.
email_verified - (hosted domain): In the response, this is empty.
hd
[!NOTE] Note: Ifisemail_verifiedandtrueis empty in the response, it implies that the account is an authorized Google Account. Currently, Google does not issue verifiable credentials for Google Workspace Accounts. However, thehdfield is present in verifiable credentials issued for non-workspace accounts. You are encouraged to implement handling this field to future-proof your app.hd -
If the email is non-@gmail.com, Google verified this email when the Google Account was created, but there is no freshness claim. Therefore, for non-Google emails, you should consider an additional challenge, such as an OTP, to verify the user. To understand the schema of the credential and the specific rules for validating fields like, refer to the Google Identity guides.
email_verified -
nonce: A unique, cryptographically secure random value is generated for each request. This is critical for security, as it prevents replay attacks.
-
: This value implies a specific type of digital credential that contains user attributes. Including this in the request is pivotal to distinguish the email verification use case.
UserInfoCredential
Next, wrap the JSON in a , create
a , and call .
openId4vpRequestGetDigitalCredentialOptionGetCredentialRequestgetCredential()要请求验证邮箱,需构建包含的。该选项需要格式为OpenID for Verifiable Presentations(OpenID4VP)请求的字符串。
GetDigitalCredentialOptionGetCredentialRequestrequestJsonOpenID4VP请求JSON必须遵循特定结构。当前提供商支持带有外层包装的JSON结构。
"digital": {"requests": [...]} val nonce = generateSecureRandomNonce()
// 此请求遵循OpenID4VP规范
val openId4vpRequest = """
{
"requests": [
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "$nonce",
"dcql_query": {
"credentials": [
{
"id": "user_info_query",
"format": "dc+sd-jwt",
"meta": {
"vct_values": ["UserInfoCredential"]
},
"claims": [
{"path": ["email"]},
{"path": ["name"]},
{"path": ["given_name"]},
{"path": ["family_name"]},
{"path": ["picture"]},
{"path": ["hd"]},
{"path": ["email_verified"]}
]
}
]
}
}
}
]
}
"""
val getDigitalCredentialOption = GetDigitalCredentialOption(requestJson = openId4vpRequest)
val request = GetCredentialRequest(listOf(getDigitalCredentialOption))请求包含以下关键信息:
-
DCQL查询:指定凭证类型和请求的声明(如
dcql_query)。你可以请求其他声明以确定验证级别,部分可能的声明如下:email_verified- :响应中的布尔值,表示邮箱是否已验证。
email_verified - (托管域名):响应中该字段为空。
hd
[!NOTE] 注意:如果响应中为email_verified且true为空,则意味着该账户是经过授权的Google账户。目前Google不为Google Workspace账户颁发可验证凭证,但非工作区账户的可验证凭证中会包含hd字段。建议实现该字段的处理逻辑,以便为应用未来扩展做准备。hd -
对于非@gmail.com邮箱,Google仅在Google账户创建时验证该邮箱,但不提供时效性声明。因此,对于非Google邮箱,应考虑添加额外验证环节,如OTP,以验证用户身份。如需了解凭证的架构以及等字段的具体验证规则,请参考Google Identity指南。
email_verified -
nonce:为每个请求生成唯一的加密安全随机值。这对安全性至关重要,可防止重放攻击。
-
:该值表示包含用户属性的特定类型数字凭证。在请求中包含此值是区分邮箱验证用例的关键。
UserInfoCredential
接下来,将 JSON包装在中,创建并调用。
openId4vpRequestGetDigitalCredentialOptionGetCredentialRequestgetCredential()Present the request to the user
向用户呈现请求
Present the user with the request, using the Credential Manager built-in UI.
try {
// Requesting Digital Credential from user...
val result = credentialManager.getCredential(activity, request)
when (val credential = result.credential) {
is DigitalCredential -> {
val responseJsonString = credential.credentialJson
// Successfully received digital credential response.
// Next, parse this response and send it to your server.
// ...
}
else -> {
// handle Unexpected State() - Up to the developer
}
}
} catch (e: Exception) {
// handle exceptions - Up to the developer
}[!NOTE] Note: There is no equivalent of Sign in with Google'sfor Digital Credentials. If no verifiable credential is found (for example, no eligible account on device), the user will be shown a "No options available" or similar system screen.preferImmediatelyAvailableCredentials
使用Credential Manager内置UI向用户呈现请求。
try {
// 向用户请求数字凭证...
val result = credentialManager.getCredential(activity, request)
when (val credential = result.credential) {
is DigitalCredential -> {
val responseJsonString = credential.credentialJson
// 成功接收数字凭证响应
// 下一步:解析此响应并发送至服务器
// ...
}
else -> {
// 处理意外状态 - 由开发者自行实现
}
}
} catch (e: Exception) {
// 处理异常 - 由开发者自行实现
}[!NOTE] 注意:数字凭证没有与Google登录的等效的选项。如果未找到可验证凭证(例如设备上没有符合条件的账户),用户将看到"无可用选项"或类似的系统界面。preferImmediatelyAvailableCredentials
Parse the response on the client
在客户端解析响应
After receiving the response, you can perform a preliminary parse on the client.
This is useful for immediately updating the UI, for example, by showing the
user's name.
[!IMPORTANT] Important: This step is not for validation. Full cryptographic verification must be performed on your server.
The following code extracts the raw Selective Disclosure JWT
(SD-JWT) and uses a helper to decode its claims.
// 1. Parse the outer JSON wrapper to get the `vp_token`
val responseData = JSONObject(responseJsonString)
val vpToken = responseData.getJSONObject("vp_token")
// 2. Extract the raw SD-JWT string
val credentialId = vpToken.keys().next()
val rawSdJwt = vpToken.getJSONArray(credentialId).getString(0)
// 3. Use your parser to get the verified claims
// Server-side validation/parsing is highly recommended.
// Assumes a local parser like the one in our SdJwtParser.kt sample
val claims = SdJwtParser.parse(rawSdJwt)
Log.d("TAG", "Parsed Claims: ${claims.toString(2)}")
// 4. Create your VerifiedUserInfo object with REAL data
val userInfo = VerifiedUserInfo(
email = claims.getString("email"),
displayName = claims.optString("name", claims.getString("email"))
)接收响应后,可在客户端进行初步解析。这有助于立即更新UI,例如显示用户姓名。
[!IMPORTANT] 重要提示:此步骤不用于验证。完整的加密验证必须在服务器端执行。
以下代码提取原始选择性披露JWT(SD-JWT)并使用辅助工具解码其声明。
// 1. 解析外层JSON包装以获取`vp_token`
val responseData = JSONObject(responseJsonString)
val vpToken = responseData.getJSONObject("vp_token")
// 2. 提取原始SD-JWT字符串
val credentialId = vpToken.keys().next()
val rawSdJwt = vpToken.getJSONArray(credentialId).getString(0)
// 3. 使用解析器获取已验证的声明
// 强烈建议在服务器端进行验证/解析
// 假设存在本地解析器,例如示例中的SdJwtParser.kt
val claims = SdJwtParser.parse(rawSdJwt)
Log.d("TAG", "Parsed Claims: ${claims.toString(2)}")
// 4. 使用真实数据创建VerifiedUserInfo对象
val userInfo = VerifiedUserInfo(
email = claims.getString("email"),
displayName = claims.optString("name", claims.getString("email"))
)Handle the response
处理响应
The Credential Manager API will return a
response.
DigitalCredentialThe following is an example of what the raw looks like, and
what the claims look like after parsing the inner SD-JWT where you get
additional metadata as well along with verified email:
responseJsonString/*
// Example of the raw JSON response from credential.credentialJson:
{
"vp_token": {
// This key matches the 'id' you set in your dcql_query
"user_info_query": [
// The SD-JWT string (Issuer JWT ~ Disclosures ~ Key Binding JWT)
"eyJhbGciOiJ...~WyI...IiwgImVtYWlsIiwgInVzZXJAZXhhbXBsZS5jb20iXQ~...~eyJhbGciOiJ..."
]
}
}
// Example of the parsed and verified claims from the SD-JWT on your server:
{
"cnf": {
"jwk": {..}
},
"exp": 1775688222,
"iat": 1775083422,
"iss": "https://verifiablecredentials-pa.googleapis.com",
"vct": "UserInfoCredential",
"email": "jane.doe.246745@gmail.com",
"email_verified": true,
"given_name": "Jane",
"family_name": "Doe",
"name": "Jane Doe",
"picture": "http://example.com/janedoe/me.jpg",
"hd": ""
}
*/[!NOTE] Note: We highly recommend that after receiving the verified email, you trigger Credential Manager's passkey creation.
Credential Manager API将返回响应。
DigitalCredential以下是原始的示例,以及解析内部SD-JWT后的声明示例(除验证邮箱外,还包含额外元数据):
responseJsonString/*
// credential.credentialJson返回的原始JSON响应示例:
{
"vp_token": {
// 此键与dcql_query中设置的'id'匹配
"user_info_query": [
// SD-JWT字符串(发行方JWT ~ 披露信息 ~ 密钥绑定JWT)
"eyJhbGciOiJ...~WyI...IiwgImVtYWlsIiwgInVzZXJAZXhhbXBsZS5jb20iXQ~...~eyJhbGciOiJ..."
]
}
}
// 在服务器端解析并验证SD-JWT后的声明示例:
{
"cnf": {
"jwk": {..}
},
"exp": 1775688222,
"iat": 1775083422,
"iss": "https://verifiablecredentials-pa.googleapis.com",
"vct": "UserInfoCredential",
"email": "jane.doe.246745@gmail.com",
"email_verified": true,
"given_name": "Jane",
"family_name": "Doe",
"name": "Jane Doe",
"picture": "http://example.com/janedoe/me.jpg",
"hd": ""
}
*/[!NOTE] 注意:强烈建议在获取验证邮箱后,触发Credential Manager的密钥创建流程。
Server-side validation for account creation
账户创建的服务器端验证
Since the retrieved email is cryptographically verified, you can omit the email
OTP verification step, significantly reducing sign-up friction and potentially
increasing conversion. This process is best handled on your server. The client
sends the raw response (containing the ) and the original nonce to a
new server endpoint.
vp_tokenFor verification, your application must send the full to
your server for cryptographic validation before creating an account or logging
the user in.
responseJsonStringThe digital credential provides two critical levels of verification for your
server:
- Authenticity of the data : Verifying the issuer () URL and the
isssignature proves that a trusted authority issued this data.SD-JWT - Identity of the presenter : Verifying the field and the Key Binding (
cnf) signature confirms that the credential is being shared by the same device it was originally issued to, preventing it from being intercepted or used on another device.kb
The validation on the server must achieve the following:
- Verify issuer : Ensure the (issuer) field matches
iss.https://verifiablecredentials-pa.googleapis.com - Verify signature: Check the signature of the SD-JWT using the public keys (JWKs) available at https://verifiablecredentials-pa.googleapis.com/.well-known/vc-public-jwks.
[!NOTE] Note: Use a standard library (such as @sd-jwt/sd-jwt-vc for Node.js) to perform the verification steps as outlined in the OpenID for Verifiable Presentations specification.
For full security, make sure that you also validate the to prevent
replay attacks.
nonceBy combining these steps, your server can validate both the authenticity of the
data and the identity of the presenter, ensuring the credential wasn't
intercepted or spoofed before provisioning the new account.
try {
// Send the raw credential response and the original nonce to your server.
// Your server must validate the response. createAccountWithVerifiedCredentials
// is a custom implementation per each RP for server side verification and account creation.
val serverResponse = createAccountWithVerifiedCredentials(responseJsonString, nonce)
// Server returns the new account info (e.g., email, name)
val claims = JSONObject(serverResponse.json)
val userInfo = VerifiedUserInfo(
email = claims.getString("email"),
displayName = claims.optString("name", claims.getString("email"))
)
// handle response - Up to the developer
} catch (e: Exception) {
// handle exceptions - Up to the developer
}由于获取的邮箱经过加密验证,可省略邮箱OTP验证步骤,显著减少注册流程的繁琐度并可能提高转化率。此流程最好在服务器端处理。客户端将包含的原始响应和原始nonce发送至新的服务器端点。
vp_token为确保验证,应用必须将完整的发送至服务器进行加密验证,然后再创建账户或让用户登录。
responseJsonString数字凭证为服务器提供两个关键级别的验证:
- 数据真实性:验证发行方()URL和SD-JWT签名,可证明数据由可信机构颁发。
iss - 展示者身份:验证字段和密钥绑定(
cnf)签名,可确认凭证由最初颁发的同一设备共享,防止凭证被拦截或在其他设备上使用。kb
服务器端验证必须实现以下目标:
- 验证发行方:确保(发行方)字段与
iss匹配。https://verifiablecredentials-pa.googleapis.com - 验证签名:使用https://verifiablecredentials-pa.googleapis.com/.well-known/vc-public-jwks提供的公钥(JWK)检查SD-JWT的签名。
[!NOTE] 注意:使用标准库(如Node.js的@sd-jwt/sd-jwt-vc)按照OpenID for Verifiable Presentations规范执行验证步骤。
为确保完全安全,还需验证以防止重放攻击。
nonce通过结合这些步骤,服务器可同时验证数据的真实性和展示者的身份,确保凭证在创建新账户前未被拦截或伪造。
try {
// 将原始凭证响应和原始nonce发送至服务器
// 服务器必须验证响应。createAccountWithVerifiedCredentials是每个RP的自定义实现,用于服务器端验证和账户创建
val serverResponse = createAccountWithVerifiedCredentials(responseJsonString, nonce)
// 服务器返回新账户信息(如邮箱、姓名)
val claims = JSONObject(serverResponse.json)
val userInfo = VerifiedUserInfo(
email = claims.getString("email"),
displayName = claims.optString("name", claims.getString("email"))
)
// 处理响应 - 由开发者自行实现
} catch (e: Exception) {
// 处理异常 - 由开发者自行实现
}Passkey creation
密钥创建
An optional but highly recommended next step after provisioning an account is to
immediately create a passkey for that account. This provides a secure,
passwordless method for the user to sign in. This flow is identical to a
standard passkey registration.
创建账户后,可选但强烈推荐的下一步是立即为该账户创建密钥。这为用户提供了一种安全的无密码登录方式。此流程与标准密钥注册流程完全相同。
WebView support
WebView支持
For the flow to work on a WebView, developers should implement a JavaScript
bridge (JS Bridge) to facilitate the handoff. This bridge allows the
Webview to signal the native app, which can then perform the actual call
to the Credential Manager API.
要在WebView中运行此流程,开发者应实现JavaScript桥接(JS Bridge)以实现交互。该桥接允许WebView向原生应用发送信号,原生应用随后可执行实际的Credential Manager API调用。
See also
另请参阅
- Overview of verified email retrieval
- Credential Manager
- 验证邮箱获取概述
- Credential Manager
Critical Security Guidelines
关键安全指南
To maintain the integrity of the email verification flow, the following security
requirements are mandatory:
- Server-side Validation : Never trust claims parsed on the client for security-sensitive operations like account creation. Send the complete, raw and the original
responseJsonStringto the app's server for full verification.nonce - Nonce Integrity : Generate a unique, cryptographically secure nonce for every request and never reuse a nonce across multiple requests to prevent replay attacks.
- Cryptographic Checks : The app's server must validate the issuer () field, the SD-JWT signature, and the presenter identity using the
issfield.cnf
为维护邮箱验证流程的完整性,必须满足以下安全要求:
- 服务器端验证:对于账户创建等安全敏感操作,绝不要信任在客户端解析的声明。将完整的原始和原始
responseJsonString发送至应用服务器进行完整验证。nonce - Nonce完整性:为每个请求生成唯一的加密安全nonce,切勿在多个请求中重复使用nonce,以防止重放攻击。
- 加密检查:应用服务器必须验证发行方()字段、SD-JWT签名以及使用
iss字段验证展示者身份。cnf