온라인
디지털 ID는 인앱 및 웹 흐름에서 모두 허용됩니다. Google 월렛의 사용자 인증 정보를 수락하려면 다음을 실행해야 합니다.
- 제공된 안내에 따라 앱 또는 웹을 사용하여 통합합니다.
- 이 양식을 작성하여 Google 월렛의 사용자 인증 정보를 수락하는 서비스 약관을 요청하고 동의합니다.
기본 요건
신분증 표시를 테스트하려면 먼저 의도한 테스트 계정을 사용하여 공개 베타 프로그램에 등록해야 합니다. 그런 다음 지정된 Google 담당자에게 세부정보를 제공합니다.
- 서비스 약관 링크
- 로고
- 웹사이트
- Play 스토어 패키지 ID (Android 앱 통합의 경우)
- 공개 베타에 참여할 때 사용한 Gmail ID
지원되는 사용자 인증 정보 형식
디지털 신분증 문서의 데이터 형식을 정의하는 여러 제안된 표준이 있으며, 그중 두 가지가 업계의 주목을 받고 있습니다.
- mdocs - ISO에서 정의했습니다.
- W3C 검증 가능한 사용자 인증 정보: W3C에서 정의합니다.
Android 인증 관리자는 두 형식을 모두 지원하지만 Google 월렛은 현재 mdoc 기반 디지털 ID만 지원합니다.
사용자 환경
애플리케이션이 ID 속성을 요청하면 다음 프로세스가 발생합니다.
사용자 인증 정보 검색: 애플리케이션이 사용 가능한 지갑을 쿼리하여 요청을 충족할 수 있는 사용자 인증 정보를 식별합니다. 그러면 Android에서 공유할 정보를 표시하는 시스템 UI 선택기를 표시합니다. 이를 통해 사용자는 사용할 사용자 인증 정보를 충분한 정보를 바탕으로 결정할 수 있습니다.
사용자 선택 및 월렛 상호작용: 사용자가 사용자 인증 정보를 선택하면 Android에서 상응하는 월렛 앱을 호출하여 거래를 완료합니다. 월렛 앱에서 자체 동의 화면을 표시하거나 생체 인식 확인을 요구할 수 있습니다.
결과: 사용자가 동의하면 선택한 ID 사용자 인증 정보가 요청하는 애플리케이션과 공유됩니다. 사용자가 거부하면 오류가 반환됩니다.
인앱
Android 앱에서 ID 사용자 인증 정보를 요청하려면 다음 단계를 따르세요.
종속 항목 업데이트
프로젝트의 build.gradle에서 인증 관리자 (베타)를 사용하도록 종속 항목을 업데이트합니다.
dependencies {
implementation("androidx.credentials:credentials:1.5.0-beta01")
// optional - needed for credentials support from play services, for devices running Android 13 and below.
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)
ID 속성 요청
앱은 ID 요청에 개별 매개변수를 지정하는 대신 CredentialOption 내에 JSON 문자열로 모두 제공합니다. 인증 관리자는 이 JSON 문자열의 콘텐츠를 검사하지 않고 사용 가능한 디지털 지갑에 전달합니다. 그러면 각 지갑은 다음을 담당합니다. - JSON 문자열을 파싱하여 ID 요청을 이해합니다. - 저장된 사용자 인증 정보 중 요청을 충족하는 사용자 인증 정보를 결정합니다(있는 경우).
W3C는 웹 API 사양의 일부로 이 JSON 요청의 구조를 공식적으로 정의할 것으로 예상됩니다. 그러나 사양은 초안 형식이며 변경될 수 있다는 점에 유의해야 합니다.
처음에는 미리보기 프로토콜을 사용하여 Google 월렛에서 ID를 가져옵니다. 이렇게 하면 웹 API 사양이 완성되는 동안 통합 및 테스트를 시작할 수 있습니다.
다음은 미리보기 프로토콜의 mdoc requestJson
샘플입니다.
{
identity: {
providers: [{
holder: {
selector: {
format: ['mdoc'],
type: 'org.iso.18013.5.1.mDL',
fields: [
'org.iso.18013.5.1.family_name',
'org.iso.18013.5.1.portrait',
]
},
params: {
nonce: '1234',
readerPublicKey: '<public_key>',
extraParamAsNeededByWallets: true,
},
},
}]
}
}
// 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)
}
}
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson)
}
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.
}
is CreateCredentialUnknownException -> {
// An unknown, usually unexpected, error has occurred. Check the
// message error for any additional debugging information.
}
is CreateCredentialCustomException -> {
// You have encountered a custom error thrown by the wallet.
// If you made the API call with a request object that's a
// subclass of CreateCustomCredentialRequest using a 3rd-party SDK,
// then you should check for any custom exception type constants
// within that SDK to match with e.type. Otherwise, drop or log the
// exception.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}
응답은 W3C에서 정의한 identityToken (JSON 문자열)을 반환합니다. 월렛 앱에서 이 응답을 작성합니다.
예:
{
"token": "<base64 encoded response>"
}
서버에서 토큰 전송 및 처리
애플리케이션은 identityToken을 수신하면 확인을 위해 애플리케이션 서버로 전송해야 합니다. 첫 번째 단계는 base64 형식에서 토큰을 디코딩하는 것입니다. 결과 바이트 배열은 다음 CDDL을 준수하는 CBOR 데이터를 나타냅니다.
CredentialDocument = {
"version": tstr, // Set to "ANDROID-HPKE-v1"
"pkEm": bstr, // Public key, in uncompressed form
"cipherText": bstr // The encrypted data
}
다음 단계는 Android 전용 전달 구조를 사용하여 ISO/IEC 18013-5:2021의 SessionTranscript를 계산하는 것입니다.
SessionTranscript = [
null, // DeviceEngagementBytes not available
null, // EReaderKeyBytes not available
AndroidHandover // Defined below
]
AndroidHandover = [
"AndroidHandoverv1", // Version number
nonce, // nonce that comes from request
appId, // RP package name
pkRHash, // The SHA256 hash of the recipient public key
]
cipherText는 HPKE 암호화를 사용하여 암호화됩니다. 복호화하려면 이전에 생성된 EC 비공개 키와 다음 설정과 함께 SessionTranscript를 추가 인증 데이터로 사용합니다.
- KEM: DHKEM(P-256, HKDF-SHA256)
- KDF: HKDF-SHA256
- AEAD: AES-128-GCM
결과로 생성된 일반 텍스트는 ISO/IEC 18013-5:2021에 정의된 DeviceResponse CBOR 바이트입니다. DeviceResponse는 ISO/IEC 18013-5:2021 9항에 따라 유효성을 검사해야 합니다. 여기에는 mdoc가 신뢰할 수 있는 발급자로부터 발급되었는지 확인하고 의도한 기기에서 응답에 서명했는지 확인하는 등의 여러 단계가 포함됩니다. OpenWallet Foundation ID 사용자 인증 정보 프로젝트의 DeviceResponseParser 클래스를 이 유효성 검사 프로세스의 일부에 사용할 수 있습니다.
웹
Chrome에서 Digital Credentials API를 사용하여 ID 사용자 인증 정보를 요청하려면 Digital Credentials API 오리진 트라이얼에 가입해야 합니다.
오프라인
Google 월렛의 신분증을 수락하려면 다음 단계를 따르세요.
- ISO 18013-5에 정의된 ID를 허용하는 리더를 빌드하거나 획득합니다.
- 허용된 ID가 진짜인지 확인하기 위해 IACA 인증서를 판독기에 로드합니다.
- 솔루션 테스트
- Google 월렛에 애플리케이션 등록
ISO 18013-5에 정의된 ID를 허용하는 리더를 빌드하거나 획득합니다.
월렛의 신분증은 모바일 운전면허증의 ISO 18013-5 표준에 따라 구현됩니다. BLE와 함께 NFC 기반 또는 QR 코드 참여를 데이터 전송 메커니즘으로 사용합니다. 따라서 표준의 이러한 측면을 구현할 수 있는 모든 기기(모바일 애플리케이션 포함)가 리더로 작동할 수 있습니다. 이 표준은 개방되어 있으므로 시장에서 사용할 수 있는 서드 파티 구현이 여러 개 있습니다. 또한 필요한 경우 기능을 직접 구현할 수도 있습니다.
이 기능을 직접 구현하는 방법에 관한 안내는 ISO 표준을 구현하고 Google 월렛의 mDL을 수락할 수 있는 오픈소스 참조 리더 Android 앱을 참고하세요.
참조 리더 앱을 빌드하고 실행하여 시작할 수 있습니다.
- 참조 앱 저장소 클론
- Android 스튜디오에서 프로젝트를 엽니다.
- Android 기기 또는 에뮬레이터에서
appverifier
타겟을 빌드하고 실행합니다.
허용된 ID가 진짜인지 확인하기 위해 IACA 인증서를 판독기에 로드합니다.
실제 사용자 인증 정보를 확인하려면 지원되는 발급기관의 지갑에 ID가 있어야 합니다. Google 월렛에서 지원하는 발급기관 목록은 인증을 위한 인증서 링크와 함께 아래에 나와 있습니다.
솔루션을 테스트하려면 오픈소스 참조 홀더 Android 애플리케이션을 빌드하고 실행합니다. 참조 홀더 앱을 빌드하고 실행하는 단계는 다음과 같습니다.
- 참조 앱 저장소 클론
- Android 스튜디오에서 프로젝트를 엽니다.
- Android 기기 또는 에뮬레이터에서
appholder
타겟을 빌드하고 실행합니다.
(선택사항) Google 월렛에 애플리케이션 등록
이 양식을 작성하여 Google 월렛에 애플리케이션을 등록합니다.