Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
이 명세는 운전면허증(PDF417) 및 여행 문서(MRZ)에서 볼 수 있는 것과 같은 광학 바코드를 Verifiable Credentials [VC-DATA-MODEL-2.0]를 사용하여 보호하는 메커니즘을 설명한다. Verifiable Credential 표현은 150바이트 미만에 들어갈 만큼 충분히 압축되어 있으므로 표준 인쇄 공정을 사용해 물리적 카드에 인쇄되는 기존의 2차원 바코드와 통합될 수 있다.
이 절은 이 문서가 발행된 시점의 상태를 설명한다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있다.
이 문서는 Verifiable Credentials Working Group이 Recommendation 트랙을 사용하여 작업 초안으로 발행했다.
작업 초안으로서의 발행은 W3C 및 그 회원의 승인을 의미하지 않는다.
이는 초안 문서이며 언제든지 다른 문서에 의해 업데이트, 대체 또는 폐기될 수 있다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않다.
이 문서는 W3C Patent Policy에 따라 운영되는 그룹에 의해 작성되었다. W3C는 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지하며, 해당 페이지에는 특허 공개를 위한 지침도 포함되어 있다. 어떤 개인이 자신이 보유한 실제 지식에 근거하여 어떤 특허가 Essential Claim(s)을 포함한다고 믿는 경우, 그 개인은 W3C Patent Policy 제6절에 따라 정보를 공개해야 한다.
이 문서는 2025년 8월 18일 W3C Process Document의 적용을 받는다.
운전면허증, 여권, 여행 자격 증명과 같은 물리적 자격 증명에는 문서에서 정보를 빠르게 읽는 데 사용할 수 있는 기계 판독 가능 데이터가 포함되는 경우가 많다. 이 정보는 PDF417 [ISO15438-2015], 기계 판독 가능 영역(MRZ) [ICAO9303-3], 및 1차원 또는 2차원 “막대” 형식으로 구성된 기타 광학적으로 스캔 가능한 코드와 같은 형식으로 인코딩된다. 그래서 “바코드”라는 용어가 사용된다. 이 정보는 변조로부터 보호되지 않는 경우가 많으며, 쉽게 구할 수 있는 바코드 생성 및 스캔 라이브러리 때문에 누구나 이러한 바코드를 생성하는 것이 상당히 쉽다.
따라서 이러한 바코드의 발급자가 바코드 안에 포함된 정보뿐만 아니라 바코드를 생성한 주체도 보호하는 것은 유용하다.
Verifiable Credentials Data Model v2.0 명세는 운전면허증이나 여행 문서에 있는 것과 같은 자격 증명 정보를 표현하기 위한 전역 표준을 제공한다. Verifiable Credential Data Integrity 1.0 명세는 자격 증명 정보를 보호하기 위한 전역 표준을 제공한다. 이 두 명세를 결합하면 자격 증명을 변조로부터 보호하고, 자격 증명의 작성 주체를 표현하며, 개인정보를 보호하는 방식으로 자격 증명의 현재 상태를 제공할 수 있다. 그러나 이러한 데이터 형식은 광학 바코드로 표현하기에는 너무 큰 경향이 있다.
Linked Data를 위한 간결한 이진 객체 표현 v1.0 명세는 보호된 검증 가능한 자격 증명을 광학 바코드로 표현하거나 광학 바코드 안에 삽입하는 것이 가능해지는 수준까지 압축하는 수단을 제공한다.
이 명세는 운전면허증(PDF417) 및 여행 문서(MRZ)에서 볼 수 있는 것과 같은 광학 바코드를, 검증 가능한 자격 증명 [VC-DATA-MODEL-2.0]을 사용해 바코드 자체 또는 바코드의 주체에 관한 정보를 표현함으로써 보호하는 메커니즘을 설명한다. 다음으로 이 Verifiable Credential은 Data Integrity [VC-DATA-INTEGRITY]를 사용하여 보호되고, 이어서 CBOR-LD [CBOR-LD]를 사용하여 압축된다.
Verifiable Credential을 사용하여 바코드를 보호할 수 있는 주요 메커니즘은 두 가지이다.
두 사용 사례 모두 Verifiable Credential로 보호되는 데이터에 대해 진정성, 무결성, 변조 방지성을 달성한다. 또한 이를 요구하는 사용 사례에서는 이러한 Verifiable Credentials를 바코드별로 폐기하거나 정지할 수 있다.
다음 절에서는 이 명세를 사용해 검증 가능한 자격 증명을 통한 디지털 서명으로 기존의 물리적 자격 증명을 향상할 수 있는 몇 가지 입문 예제를 제공한다.
이 절에서는 이 명세의 기술을 사용하여 PDF417 바코드를 사용하는 운전면허증의 광학 바코드를 보호하는 방법에 대한 예를 제공한다. 예제 운전면허증으로 시작한다.
운전면허증의 뒷면에는 PDF417 바코드가 포함되어 있다.
PDF417 데이터에는 이 명세에서 설명하는 알고리즘을 사용해 보호되는 정보가 포함되어 있다. 즉, PDF417 바코드에는 다음 형식의 검증 가능한 자격 증명이 포함된다.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vdl/v2",
"https://w3id.org/vdl/utopia/v1"
],
"type": [
"VerifiableCredential",
"OpticalBarcodeCredential"
],
// 아래 issuer 값은 위의 'utopia/v1' 컨텍스트에서 URL로 정의된다
"issuer": "did:web:dmv.utopia.example",
"credentialStatus": {
"type": "TerseBitstringStatusListEntry",
"terseStatusListBaseUrl": "https://dmv.utopia.gov/statuses/12345/status-lists"
"terseStatusListIndex": 123567890
},
"credentialSubject": {
"type": "AamvaDriversLicenseScannableInformation",
"protectedComponentIndex": "uP_BA"
},
"proof": {
"type": "DataIntegrity",
"cryptosuite": "ecdsa-xi-2023",
// 아래 공개 키는 위의 'utopia/v1' 컨텍스트에서 URL로 정의된다
"verificationMethod": "did:web:dmv.utopia.example#key-1",
"proofPurpose": "assertionMethod",
"proofValue": "z4peo48uwK2EF4Fta8P...HzQMDYJ34r9gL"
}
}
위의 검증 가능한 자격 증명은 그런 다음 [CBOR-LD]를 사용해 다음 출력으로 압축된다(CBOR Diagnostic Notation).
1281{
1 => [ 32768, 32769, 32770], // @context
155 => [ 116, 164 ], // type
192 => 174, // issuer
186 => { 154 => 166, 206 => 178, 208 => 1234567890 }, // credentialStatus
188 => { 154 => 172, 180 => h'753FF040 }, // credentialSubject
194 => { // proof
154 => 108, // type
214 => 4, // cryptosuite
224 => 230 // verificationMethod
228 => 176, // proofPurpose
210 => Uint8Array(65) [ ... ], // proofValue
}
}
이 절에서는 이 명세의 기술을 사용하여 출생증명서를 검증 가능한 자격 증명으로 보호하고, 이를 인쇄된 종이 문서 위의 QR Code로 표현하는 방법에 대한 예를 제공한다.
QR Code는 다음 검증 가능한 자격 증명을 인코딩한다. 인코딩의 세부 사항은 아래의 별도 탭에서 확인할 수 있다.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vital-records/v1rc1"
],
"type": [
"VerifiableCredential",
"BirthCertificateCredential"
],
"issuer": "https://hospital.example/issuer",
"validFrom": "2023-09-30T11:30:00Z",
"credentialSubject": {
"type": "BirthCertificate",
"certificationDate": "2023-09-30T13:44:52Z",
"newborn": {
"type": "Newborn",
"name": "Tim Doe",
"gender": "Male",
"birthDate": "2023-10-05T14:29:00Z",
"birthPlace": {
"type": "PostalAddress",
"streetAddress": "123 Hospital Rd",
"addressLocality": "Utopia Town",
"addressRegion": "Utopolis",
"postalCode": "12345",
"addressCountry": "Utopia"
},
"parent": [{
"type": "Mother",
"name": "Jane Doe",
"namePriorToMarriage": "Jane Smith"
}, {
"type": "Father",
"name": "John Doe"
}]
}
}
}
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vital-records/v1rc1"
],
"type": [
"VerifiableCredential",
"BirthCertificateCredential"
],
"issuer": "https://hospital.example/issuer",
"validFrom": "2023-09-30T11:30:00Z",
"credentialSubject": {
"type": "BirthCertificate",
"certificationDate": "2023-09-30T13:44:52Z",
"newborn": {
"type": "Newborn",
"name": "Tim Doe",
"gender": "Male",
"birthDate": "2023-10-05T14:29:00Z",
"birthPlace": {
"type": "PostalAddress",
"streetAddress": "123 Hospital Rd",
"addressLocality": "Utopia Town",
"addressRegion": "Utopolis",
"postalCode": "12345",
"addressCountry": "Utopia"
},
"parent": [
{
"type": "Mother",
"name": "Jane Doe",
"namePriorToMarriage": "Jane Smith"
},
{
"type": "Father",
"name": "John Doe"
}
]
}
},
"proof": {
"type": "DataIntegrityProof",
"created": "2026-06-23T17:09:43Z",
"verificationMethod": "did:key:zDnaep3M6F9WVbtR4JaDCpS84JphmppHXBh8NNLWQYJDvpa8i",
"cryptosuite": "ecdsa-rdfc-2019",
"proofPurpose": "assertionMethod",
"proofValue": "z5dT3pjsBWEXyquJXoNX1atkXDisQaLJMcrkJPNYMSMqSMocrqhHkK9nRiztfTDSANzg5iEi6YurddLfD
nnStdeTm"
}
}
51997(
[
1,
{
1: [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vital-records/v1rc1"
],
157: [
118,
164
],
304: {
156: 162,
204: "2023-09-30T13:44:52Z",
260: {
150: "Tim Doe",
156: 174,
188: "2023-10-05T14:29:00Z",
196: {
156: 178,
324: "Utopia",
326: "Utopia Town",
328: "Utopolis",
330: "12345",
332: "123 Hospital Rd"
},
226: "Male",
267: [
{
150: "Jane Doe",
156: 172,
258: "Jane Smith"
},
{
150: "John Doe",
156: 170
}
]
}
},
308: [
2,
"hospital.example/issuer"
],
310: {
156: 108,
336: 1782234583,
338: "ecdsa-rdfc-2019",
348: 354,
350: h'7ae780156acdf39b8a76dd9dfdcc7d9cf32636e91579f894a2f1fc8cafc9fd0fb5a72660ed343f1ca8854
2eafd94e542c509080ab479da5e303fb74dcdd2065674',
352: [
1025,
h'8024035ecd0dd569e4db7f6feefdb0249d9156db32899632ae707466310043e3cb954b'
]
},
320: 1696073400
}
])}
VC1-R0OR*W3H90Q80L8FA9DIWENPEJ/5S4F03F53F7*5$KE$:5CPEXPC C1$CBWEAECCPEI.EL8FA9DIWENPEJ/553FPED7*5$K
E006-EDAECOX5Z C04EKVC006DB6DOC1534KG$-EOXKY60$RK0XJ6MK5%PNF6QF63W5CA79L6/SAJL6:Q66G7KG6B73KQ0*43$2D
YEDP34W3E053I53W531VE8466L6$963W5HX6-963G7PA7646OHBW%O053M53B735T86 A/3EMEDB73R+86 A/3EMED-3454EF-DD
70O8DHWES9EXVDZOEF70UZCQF60R6B73$T9*96%K6379WQE-EDAEC*34JTC-RS9Z9TVDB73LK1$RKT0J6I91/DP34W3E053G53B7
3XD06I91/D+34J$DAWE6MKT0JKI949DP34W3E053E53B73WS61E059DWQE-EDAEC.%5$9FQ$DTVDW:5ZQE%$E4JE+60+:K0XJ/TD
L70CF37J7U8RN70W3EJPCHQEOX57VC9OCNF61A6B73.SB*70B73W-BMC88VI17O7KH*PAHK7DEN BQ$HAPSE/EE451E7EPCRGYJZ
V5TPNQ62SAJO2AUSG2DUDIO 2IOER26ON44.4M:-QVC0%ZBY+M/ACB7319CE73T70/L4*O4E:BVX1IHDVXRY6E93WDS4 GI:VRWH
HEI6X9EG-CM10+ZSE*IB73U485ZCA%0
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vital-records/v1rc1"
],
"type": [
"VerifiableCredential",
"BirthCertificateCredential"
],
"issuer": "https://hospital.example/issuer",
"validFrom": "2023-09-30T11:30:00Z",
"credentialSubject": {
"type": "BirthCertificate",
"certificationDate": "2023-09-30T13:44:52Z",
"newborn": {
"type": "Newborn",
"name": "Tim Doe",
"gender": "Male",
"birthDate": "2023-10-05T14:29:00Z",
"birthPlace": {
"type": "PostalAddress",
"streetAddress": "123 Hospital Rd",
"addressLocality": "Utopia Town",
"addressRegion": "Utopolis",
"postalCode": "12345",
"addressCountry": "Utopia"
},
"parent": [
{
"type": "Mother",
"name": "Jane Doe",
"namePriorToMarriage": "Jane Smith"
},
{
"type": "Father",
"name": "John Doe"
}
]
}
},
"proof": {
"type": "DataIntegrityProof",
"created": "2026-06-23T17:09:43Z",
"verificationMethod": "did:key:zDnaep3M6F9WVbtR4JaDCpS84JphmppHXBh8NNLWQYJDvpa8i",
"cryptosuite": "ecdsa-rdfc-2019",
"proofPurpose": "assertionMethod",
"proofValue": "z3xU4Hqfs6EKrrwiRyNP6Pwxfo8yHfyHA5SFt4Dn9cSfQVcqDsCzSeD8CSDs2XqU7Y4qB6zkWrJqt9t2P
s13mzgoA"
}
}}
다음은 이 명세의 기술에 대한 설계 목표이다.
이 문서 전체에서 사용되는 용어는 Verifiable Credentials Data Model v2.0 명세의 용어 절과 Verifiable Credential Data Integrity 1.0 명세에 정의되어 있다.
A 및 B)의 순서를
결정하는 것을 말한다. 이 정의는 코드 포인트를 비교하는
문자열의
전순서를 정의한다.
UTF-8로 인코딩된 문자열의 경우 바이트 시퀀스를 비교하면 코드
포인트 순서와 동일한 결과가 나온다는 점에 유의한다.
비규범으로 표시된 절뿐만 아니라, 이 명세의 모든 작성 지침, 도표, 예제, 참고는 비규범이다. 이 명세의 그 밖의 모든 것은 규범이다.
이 문서에서 핵심어 MAY, MUST, RECOMMENDED, REQUIRED, 및 SHOULD는 여기 표시된 것처럼 모두 대문자로 나타나는 경우에 한해서 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석되어야 한다.
적합 문서는 이 명세의 규범적 진술을 준수하는 데이터 모델의 모든 구체적 표현이다. 구체적으로 이 문서의 2. 데이터 모델 및 3. 알고리즘 절의 모든 관련 규범적 진술은 MUST 시행되어야 한다.
적합 프로세서는 적합 문서를 생성하거나 소비하는 소프트웨어 및/또는 하드웨어로 실현된 모든 알고리즘이다. 적합 프로세서는 비적합 문서를 소비할 때 오류를 생성해야 MUST 한다.
이 문서에는 JSON 및 JSON-LD 데이터 예제가 포함되어 있다. 이러한 예제 중 일부는
인라인 주석(//)처럼 특정 부분을 설명하는 기능과
예제와 관련 없는 정보의 생략을 나타내는 줄임표(...)를 포함하므로
유효하지 않은 JSON이다. 구현자가 예제를 유효한 JSON 또는 JSON-LD로 취급하려는 경우
이러한 부분은 제거해야 한다.
다음 절들은 이 명세가 바코드 및 여행 문서의 기계 판독 가능 영역과 같은 광학적으로 인쇄된 정보를 보호하는 검증 가능한 자격 증명을 표현하는 데 사용하는 데이터 모델을 개괄한다.
OpticalBarcodeCredential은 광학 바코드의 내용을 보호하는 데 사용되며,
1) 작성자 정보, 2) 변조 방지성, 3) 선택적으로 폐기 및 정지 상태를 제공한다.
다시 말해, 이 자격 증명은 광학 바코드를 누가 발급했는지, 광학 바코드가
처음 발급된 이후 변조되었는지, 그리고 광학 바코드의 발급자가
문서가 여전히 유효한지 여부를 아직 보증하는지를 알려줄 수 있다. 이러한 기능은
물리적 문서에 대해 상당한 사기 방지 보호를 제공한다.
OpticalBarcodeCredential의 credentialSubject는
AamvaDriversLicenseScannableInformation 또는 MachineReadableZone
타입 중 하나이다. AamvaDriversLicenseScannableInformation은
검증 가능한
자격 증명이
물리적 문서의 PDF417 바코드와
검증 가능한
자격 증명에
표현된 정보를 보호한다는 것을 의미한다.
MachineReadableZone은
검증 가능한
자격 증명이
물리적 문서의 기계 판독 가능 영역과
검증 가능한
자격 증명에
표현된 정보를 보호한다는 것을 의미한다.
OpticalBarcodeCredential이
AamvaDriversLicenseScannableInformation 타입인 경우,
PDF417에서 어떤 필드가 디지털 서명되는지에 대한 정보를 포함하는
REQUIRED 추가 필드 protectedComponentIndex가 있다.
protectedComponentIndex는 3바이트/24비트 값이어야 MUST
하며, JSON-LD 자격 증명에서 총 5문자가 되도록 multibase-base64url로 인코딩된다.
AAMVA 준수 운전면허증 PDF417 [aamva-dl-id-card-design-standard]에는
22개의 필수 필드가 있으며, protectedComponentIndex 값의 처음 22비트는
이 필드들에 대응한다. 각 AAMVA 필수 필드는 세 문자 요소 ID(예: 문서 만료일의
DBA)로 시작한다. protectedComponentIndex 값의 비트와
이러한 필드 사이의 매핑을 구성하려면, 이러한 요소 ID를 Unicode 코드 포인트 순서에
따라 정렬한다. 그런 다음 protectedComponentIndex의 위치 i에 있는
비트가 1이면, 정렬된 요소 ID의 위치 i에 있는 AAMVA 필수 필드는
디지털 서명에 의해 보호된다. protectedComponentIndex의 마지막 두 비트는
0이어야 MUST 한다. 자세한 내용은 Section 3.2.4.4
opticalDataBytes 생성을 참조한다.
가능한 한 높은 압축률을 달성하기 위해, issuer 및 verificationMethod
필드는 JSON-LD Context의 용어를 활용하는 것이 RECOMMENDED되며,
그러면 CBOR-LD의 의미 기반 압축 메커니즘 덕분에 몇 바이트 수준으로 압축될 수 있다.
이 절에 지정된 속성을 활용하는 광학 바코드 자격 증명의 예는 아래와 같다.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vdl/v2",
"https://w3id.org/vdl/utopia/v1"
],
"type": [
"VerifiableCredential",
"OpticalBarcodeCredential"
],
"issuer": "did:web:dmv.utopia.example",
"credentialStatus": {
"type": "TerseBitstringStatusListEntry",
"terseStatusListBaseUrl": "dmv.utopia.gov/statuses/12345/status-lists"
"terseStatusListIndex": 123567890
},
"credentialSubject": {
"type": "AamvaDriversLicenseScannableInformation",
"protectedComponentIndex": "uP_BA"
}
}
TerseBitstringStatusListEntry는 Bitstring Status List v1.0
명세에 정의된 BitstringStatusListEntry의 간결한 표현이다.
TerseBitstringStatusListEntry 타입의 객체는 두 개의 추가 속성을 가져야
MUST 한다.
terseStatusListBaseUrl은 이 자격 증명과 연결된 상태 목록의 위치를 식별한다.
terseStatusListBaseUrl은 URL [URL]이어야
MUST 한다.
terseStatusListIndex는 위 URL의 개별 상태를 지정한다.
terseStatusListIndex는 32비트 부호 없는 정수로 표현 가능해야
MUST 한다.
TerseBitstringStatusListEntry를 처리하려면, Section
3.2.3 상태 목록 항목 변환의 알고리즘을 적용하여 이를
BitstringStatusListEntry로 변환한 다음,
Bitstring Status List v1.0에서처럼
처리한다.
구현자는 개별 상태 목록의 길이에 대해 listLength 값을 설정해야 한다. 그러면
32비트 terseStatusListIndex에 대해 상태 목록 수
listCount = 2^32 / listLength가 산출된다.
listLength는 TerseBitstringStatusListEntry를
BitstringStatusListEntry로 변환하는 데 필요하다.
listLength의 일부 값은 이러한 상태 목록의 개인정보 보호 속성을 해칠 수 있다는 점에
유의하여, 구현은 listLength = 2^26 및 listCount
= 2^6을 사용해야 MUST 한다.
구현자가 CBOR-LD로 인코딩된
AamvaDriversLicenseScannableInformation
자격 증명을 PDF417에 인코딩하기 전에 base64url로 문자 인코딩하는 것이
RECOMMENDED된다. 멀티베이스 헤더는 base로 인코딩된 VCB 데이터 앞에
붙일 수 MAY 있다. PDF417 필드 헤더 명세는 멀티베이스 헤더가
있는지 없는지를 나타낼 것으로 예상된다.
구현자가 CBOR-LD로 인코딩된
MachineReadableZone 자격 증명을 QR 코드에 인코딩하기 전에
문자열 'VC1-'를 앞에 붙인 base45-multibase로 다시 인코딩하는 것이
REQUIRED된다.
다음 절은 운전면허증 및 여행 문서와 같은 물리 매체의 바코드 및 기계 판독 가능 영역과 같은 광학 정보를 보호하는 디지털 증명을 추가하고 검증하기 위한 알고리즘을 설명한다.
이 절에는 검증 가능한 자격 증명의 인코딩 및 디코딩에 일반적으로 적용되는 알고리즘이 포함된다.
이 명세는 검증 가능한 자격 증명을 인코딩하고 디코딩할 때 애플리케이션별 압축 테이블을 CBOR-LD 프로세서에 제공할 것을 요구한다. 다양한 발급자에 대한 모든 컨텍스트 URL의 레지스트리는 쉼표로 구분된 값 파일로 제공되며, 추가 전용 및 선착순 방식으로 해당 파일에 대한 변경 요청을 통해 업데이트하고 수정할 수 있다. 구현은 압축 및 압축 해제가 최신 값을 지원하도록 보장하기 위해 매월 최신 파일을 가져와 활용해야 SHOULD 한다.
다음 알고리즘은 검증 가능한 자격 증명을 QR Code로 표현할 수 있는 텍스트 문자열로 인코딩하는 방법을 지정한다. 필수 입력은 검증 가능한 자격 증명(map inputDocument)과 옵션 집합 (map options)이다. 출력은 인코딩된 검증 가능한 자격 증명 (string) 또는 오류이다. 이 알고리즘이 문자열을 인코딩할 때마다 UTF-8 인코딩을 사용해야 MUST 한다.
45를
targetBase로,
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:를 baseAlphabet로 전달하여
Base Encoding 알고리즘을 수행한 결과를
base45Value로 둔다.
VC1-,
R(base45의 Multibase 접두사),
및
base45Value.
다음 알고리즘은 QR Code로 인코딩된 검증 가능한 자격 증명을 디코딩하는 방법을 지정한다. 필수 입력은 텍스트 문자열(string inputDocument)과 옵션 집합(map options)이다. 출력은 검증 가능한 자격 증명(map) 또는 오류이다. 이 알고리즘이 문자열을 인코딩할 때마다 UTF-8 인코딩을 사용해야 MUST 한다.
VC1-R로 시작하는지 확인한다. 그렇지 않으면
오류가 발생되어야 MUST 한다.
VC1-R)를
제거한 것을 base45Value로 둔다.
45를
sourceBase로,
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:를 baseAlphabet로 전달하여
Base Decoding 알고리즘을 수행한 결과를
cborldDocument로 둔다.
이 절에는 type이 OpticalBarcodeCredential인
검증 가능한
자격 증명의
인코딩 및 디코딩에 특화된 알고리즘이 포함된다.
OpticalBarcodeCredential에
추가하려는 BitstringStatusListCredential
(Bitstring Status List
v1.0 명세에 정의된 것)으로 설정한다.
TerseBitstringStatusListEntry로
설정하고, statusListEntryTerse.index를
statusListEntryVerbose.statusListIndex의 정수 표현으로 설정한다.
OpticalBarcodeCredential로 설정한다.
OpticalBarcodeCredential로 설정한다.
이 절의 알고리즘은 TerseBitstringStatusListEntry를
BitstringStatusListEntry로 변환하는 데 사용된다. 이는
검증
가능한
자격 증명에 대한 검증이 수행된 후, 유효성 검사 과정에서 사용된다.
검증
가능한
자격 증명 검증이 수행된 후, 이 알고리즘은 OpticalBarcodeCredential
검증
가능한
자격 증명
(struct vc),
vc와 연결된 BitstringStatusListCredential의 항목 수를 포함하는 정수
listLength, 그리고 문자열 statusPurpose(예: 'revocation', 'suspension'...)를
입력으로 받아 'BitstringStatusListEntry' 객체를 반환한다.
floor() 연산 적용)으로 설정한다.
result는 Bitstring Status List v1.0 명세의 유효성 검사 알고리즘에 대한 입력으로 사용할 수 있다.
구현자는 모든 발급자가 자신의 검증 가능한 자격 증명에 대한 상태 목록 정보를 게시하지는 않는다는 점에 유의해야 한다. 일부 발급자는 검증자가 상태 목록 자격 증명에 접근하도록 허용하기 전에 권한 부여를 요구할 수 있다.
ecdsa-xi-2023 cryptosuite는 사실상 ecdsa-rdfc-2019
알고리즘 [VC-DI-ECDSA]에
원래 광학 바코드 데이터와 같은 일부 “extra information”(xi)을 입력으로 받아
그 데이터를 디지털 서명으로 보호되는 정보에 포함하는 단계를 추가한 것이다. 이 절의 알고리즘은
이러한 서명이 어떻게 생성되고 검증되는지 자세히 설명한다.
증명을 생성하려면 Data Integrity [VC-DATA-INTEGRITY] 명세의 Section 4.1: Add Proof에 있는 알고리즘을 실행해야 MUST 한다. 해당 알고리즘에 대해, cryptographic suite specific transformation algorithm은 Data Integrity ECDSA Cryptosuites v1.0의 Transformation (ecdsa-rdfc-2019) 절에 정의되고, hashing algorithm은 Section 3.2.4.3 해싱 (ecdsa-xi-2023)에 정의되며, proof serialization algorithm은 Data Integrity ECDSA Cryptosuites v1.0의 Proof Serialization (ecdsa-rdfc-2019) 절에 정의된다.
증명을 검증하려면 Data Integrity [VC-DATA-INTEGRITY] 명세의 Section 4.2: Verify Proof에 있는 알고리즘을 실행해야 MUST 한다. 해당 알고리즘에 대해, cryptographic suite specific transformation algorithm은 Data Integrity ECDSA Cryptosuites v1.0의 Transformation (ecdsa-rdfc-2019) 절에 정의되고, hashing algorithm은 Section 3.2.4.3 해싱(ecdsa-xi-2023)에 정의되며, proof verification algorithm은 Data Integrity ECDSA Cryptosuites v1.0의 Proof Verification (ecdsa-rdfc-2019) 절에 정의된다.
해싱 알고리즘은 Data Integrity ECDSA Cryptosuites v1.0 명세의 Hashing (ecdsa-rdfc-2019) 절에 정의된 것에, 아래에 설명된 광학 데이터의 해싱을 추가한 것이다. 구현이 기계 판독 가능 광학 데이터(PDF417 또는 MRZ 데이터)를 이 해싱 알고리즘에 사용할 수 있게 한다고 가정한다.
이 알고리즘의 필수 입력은 transformed data document (transformedDocument), canonical proof configuration (canonicalProofConfig), 그리고 optical data (opticalDataBytes)이다. 바이트 시퀀스로 표현되는 단일 hash data 값이 출력으로 생성된다.
해싱 알고리즘은 Data Integrity ECDSA Cryptosuites v1.0의 Hashing (ecdsa-rdfc-2019) 절에 정의된 것이며, 3단계를 다음 두 단계로 대체한다.
credentialSubject.protectedComponentIndex를 multibase-base64url에서
이진으로 디코딩한 결과인 길이 24비트 bitstring의 처음 22비트를
bitfieldDecoded로 설정한다.
1인 각 비트에 대해:
\n, U+000A)를 끝에 연결한 다음,
그 결과를 dataToCanonicalize에 추가한다.
증명 구성 알고리즘은 Data Integrity ECDSA Cryptosuites v1.0의 Proof Configuration (ecdsa-rdfc-2019) 절에 정의된 것이며, 4단계를 다음 단계로 대체한다.
DataIntegrityProof로 설정되어 있지 않고
proofConfig.cryptosuite가 ecdsa-xi-2023으로 설정되어 있지 않으면,
INVALID_PROOF_CONFIGURATION 오류가 발생되어야
MUST 한다.
이 절은 비규범이다.
이 절을 읽기 전에 독자는 Data Integrity 명세의 보안 고려사항 절에서 제공하는 일반적인 보안 조언과 ECDSA Cryptosuites 명세의 보안 고려사항 절에서 제공하는 구체적인 보안 조언을 숙지할 것을 권장한다.
다음 절들에서는 이러한 중요한 사항들을 검토하고 독자를 추가 정보로 안내한다.
OpticalBarcodeCredentials에 대한 한 공격 벡터는 디지털 서명이 포함된
광학 바코드를 복제하여 위조 문서에 사용하는 것이다. 복제된 바코드는 원본처럼
서명 검증을 통과하지만, 이 공격은 문서 검증자가 다음 세 가지를 확인함으로써
완화된다. 서명된 데이터가 문서에 보이는 데이터와 일치하는지, 서명된 데이터가
사용자의 물리적 속성과 일치하는지, 그리고 보이는 데이터가 사용자의 물리적 속성과
일치하는지이다. 이 세 가지가 모두 동일할 때, OpticalBarcodeCredential이
중복일 수 있는 유일한 경우는 위조 문서 작성자가 위조 문서 사용자의 물리적 속성과
서명된 물리적 속성이 완전히 겹치는 실제 OpticalBarcodeCredential에
접근할 수 있었던 경우이다. 임의의 사람의 외형과 완전히 일치하는 도난된
OpticalBarcodeCredential이 탐지되지 않은 채 존재할 가능성이 낮기 때문에,
이 공격은 성공하기 어렵다.
어떤 경우에는 기존 광학 데이터 전체에 대해 디지털 서명을 생성할 수 없을 수도 있다.
예를 들어 물리적 자격 증명 제조업체가 일련번호를 삽입하여 서명 시점에는 발급자가
이를 알 수 없는 경우를 고려한다. 이 경우 검증자는 디지털 서명되지 않은 모든 데이터가
OpticalBarcodeCredential의 성공적인 검증 능력에 영향을 주지 않고
광학 바코드에서 변경되었을 수 있다고 가정한다.
광학 바코드의 데이터가 문서에 보이는 데이터 및 문서 소지자의 특성과 일치하는지 확인할 때, 구현자는 디지털 서명된 필드만 사용할 것을 권장한다. 검증자는 다른 필드가 서명되지 않은 문서의 사기 탐지에 얼마나 흔히 사용되는지와 관계없이, 디지털 서명으로 보호되는 필드만 사용할 것을 권장한다. 예를 들어 눈 색상과 머리카락 색상이 서명으로 보호되지만 소지자의 초상은 그렇지 않은 경우, 검증자는 초상보다 눈 색상과 머리카락 색상에 중점을 두어 사기 탐지를 시도할 것을 권장한다.
검증자가 사용하는 소프트웨어의 구현자는 검증 과정에서 디지털 서명으로 보호된 카드 데이터만 표시할 것을 권장한다. 변조되었을 수 있는 서명되지 않은 데이터를 표시하면 사기 탐지를 방해할 수 있다.
검증자는
OpticalBarcodeCredential의 유효성을 확인하기 위해 항상 신뢰할 수 있는
프로그램과 인터페이스를 사용할 것을 권장한다. 신뢰할 수 없는 소프트웨어를 사용해
문서를 검증하면 위조 자격 증명이 수락되거나 진짜 자격 증명이 도난당할 수 있다.
이 절을 읽기 전에 독자는 Data Integrity 명세의 보안 고려사항 절에서 제공하는 일반적인 보안 조언과 ECDSA Cryptosuites 명세의 보안 고려사항 절에서 제공하는 구체적인 보안 조언을 숙지할 것을 권장한다.
다음 절은 이 명세를 구현하는 개발자가 개인정보 보호 가정을 위반하지 않기 위해 알고 있어야 하는 개인정보 보호 고려사항을 설명한다.
이 절은 비규범이다.
이 절에는 Verifiable Credential Barcodes의 예와 함께, 그것들이 어떻게 생성되고 어떻게 검증되는지에 대한 단계별 과정이 포함되어 있다.
이 절에서는 두 가지 실행 예제를 분석한다. Utopia Employment Authorization Document의 MRZ를 보호하는 VCB와 Utopia Driver's License의 PDF417을 보호하는 VCB이다.
먼저 VCB가 서명할 데이터, 즉 PDF417의 필수 AAMVA 필드로 시작한다.
DACJOHN DADNONE DAG123 MAIN ST DAIANYVILLE DAJUTO DAKF87P20000 DAQF987654321 DAU069 IN DAYBRO DBA04192030 DBB04191988 DBC1 DBD01012024 DCAC DCBNONE DCDNONE DCFUTODOCDISCRIM DCGUTO DCSSMITH DDEN DDFN DDGN
단순화를 위해, PDF417에서 서명하려는 유일한 데이터가 이름(DAC),
성(DCS), 그리고 면허 번호(DAQ)라고 가정한다.
protectedComponentIndex에 사용할 bitstring 값은
100000100000000000100000이고, protectedComponentIndex의 값은
"uggAg"이다.
3.2.4.4
opticalDataBytes 생성을 적용하면 다음을 얻는다.
canonicalizedData = 'DACJOHN\nDAQF987654321\nDCSSMITH\n' opticalDataBytes: [188, 38, 200, 146, 227, 213, 90, 250, 50, 18, 126, 254, 47, 177, 91, 23, 64, 129, 104, 223, 136, 81, 116, 67, 136, 125, 137, 165, 117, 63, 152, 207]
이제 이 해시 값을
3.2.4.3 해싱
(ecdsa-xi-2023)과 함께 사용하여 VC에 서명할 수 있다.
BitstringStatusListCredential로
3.2.1
OpticalBarcodeCredential 인코딩을 실행하면 다음 JSON-LD VC를 얻는다.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vc-barcodes/v1",
"https://w3id.org/utopia/v2"
],
"type": [
"VerifiableCredential",
"OpticalBarcodeCredential"
],
"credentialSubject": {
"type": "AamvaDriversLicenseScannableInformation",
"protectedComponentIndex": "uggAg"
},
"issuer": "did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj",
"credentialStatus": {
"type": "TerseBitstringStatusListEntry",
"terseStatusListBaseUrl": "https://sandbox.platform.veres.dev/statuses/z19rJ4oGrbFCqf3cNTVDHSbNd/status-lists",
"terseStatusListIndex": 3851559041
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj#zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj",
"cryptosuite": "ecdsa-xi-2023",
"proofPurpose": "assertionMethod",
"proofValue": "z4g6G3dAZhhtPxPWgFvkiRv7krtCaeJxjokvL46fchAFCXEY3FeX2vn46MDgBaw779g1E1jswZJxxreZDCrtHg2qH"
}
}
이제 이 VC에 CBOR-LD 압축을 적용할 수 있다. 여기서는 최신 버전의 CBOR-LD를 사용하지만, 이 절의 끝에서는 최신 상태가 아닌 CBOR-LD 구현과의 상호운용성 테스트를 위해 이전 버전의 CBOR-LD로 인코딩된 VCB도 제공한다.
이 명세를 위해 값 100을 가진 CBOR-LD 레지스트리 항목을 예약했다
(즉, 이러한 페이로드는 태그 0x0664로 시작한다). CBOR-LD를 사용해
인코딩하기 위한 매개변수는 CBOR-LD 명세의 레지스트리에서 찾을 수 있으며,
다음과 같다.
registryEntryId: 100
typeTable:
{
"context":
{
"https://www.w3.org/ns/credentials/v2": 32768,
"https://w3id.org/vc-barcodes/v1": 32769,
"https://w3id.org/utopia/v2": 32770
},
"https://w3id.org/security#cryptosuiteString":
{
"ecdsa-rdfc-2019": 1,
"ecdsa-sd-2023": 2,
"eddsa-rdfc-2022": 3,
"ecdsa-xi-2023": 4
}
}
컨텍스트를 처리하고 컨텍스트 용어에 정수 값을 할당한 결과로 생성되어야 하는 term-to-ID 매핑은 다음과 같다.
Map(97) {
'@context' => 0,
'@type' => 2,
'@id' => 4,
'@value' => 6,
'@direction' => 8,
'@graph' => 10,
'@included' => 12,
'@index' => 14,
'@json' => 16,
'@language' => 18,
'@list' => 20,
'@nest' => 22,
'@reverse' => 24,
'@base' => 26,
'@container' => 28,
'@default' => 30,
'@embed' => 32,
'@explicit' => 34,
'@none' => 36,
'@omitDefault' => 38,
'@prefix' => 40,
'@preserve' => 42,
'@protected' => 44,
'@requireAll' => 46,
'@set' => 48,
'@version' => 50,
'@vocab' => 52,
'...' => 100,
'BitstringStatusList' => 102,
'BitstringStatusListCredential' => 104,
'BitstringStatusListEntry' => 106,
'DataIntegrityProof' => 108,
'EnvelopedVerifiableCredential' => 110,
'EnvelopedVerifiablePresentation' => 112,
'JsonSchema' => 114,
'JsonSchemaCredential' => 116,
'VerifiableCredential' => 118,
'VerifiablePresentation' => 120,
'_sd' => 122,
'_sd_alg' => 124,
'aud' => 126,
'cnf' => 128,
'description' => 130,
'digestMultibase' => 132,
'digestSRI' => 134,
'exp' => 136,
'iat' => 138,
'id' => 140,
'iss' => 142,
'jku' => 144,
'kid' => 146,
'mediaType' => 148,
'name' => 150,
'nbf' => 152,
'sub' => 154,
'type' => 156,
'x5u' => 158,
'AamvaDriversLicenseScannableInformation' => 160,
'MachineReadableZone' => 162,
'OpticalBarcodeCredential' => 164,
'TerseBitstringStatusListEntry' => 166,
'protectedComponentIndex' => 168,
'did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj' => 170,
'did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj#zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj' => 172,
'did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj' => 174,
'did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj#zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj' => 176,
'https://sandbox.platform.veres.dev/statuses/z19rJ4oGrbFCqf3cNTVDHSbNd/status-lists' => 178,
'confidenceMethod' => 180,
'credentialSchema' => 182,
'credentialStatus' => 184,
'credentialSubject' => 186,
'evidence' => 188,
'issuer' => 190,
'proof' => 192,
'refreshService' => 194,
'relatedResource' => 196,
'renderMethod' => 198,
'termsOfUse' => 200,
'validFrom' => 202,
'validUntil' => 204,
'terseStatusListBaseUrl' => 206,
'terseStatusListIndex' => 208,
'challenge' => 210,
'created' => 212,
'cryptosuite' => 214,
'domain' => 216,
'expires' => 218,
'nonce' => 220,
'previousProof' => 222,
'proofPurpose' => 224,
'proofValue' => 226,
'verificationMethod' => 228,
'assertionMethod' => 230,
'authentication' => 232,
'capabilityDelegation' => 234,
'capabilityInvocation' => 236,
'keyAgreement' => 238
}
위 내용에 대한 자세한 정보는 6.3 구현 참고사항을 참조한다.
그 결과 다음 인코딩된 자격 증명이 생성된다.
D9CB1D821864A60183198000198001198002189D82187618A418B8A3189C18A618CE18B218D01AE592208118BAA2189C18A018A8447582002018BE18AA18C0A5189C186C18D60418E018E618E258417AB7C2E56B49E2CCE62184CE26818E15A8B173164401B5D3BB93FFD6D2B5EB8F6AC0971502AE3DD49D17EC66528164034C912685B8111BC04CDC9EC13DBADD91CC18E418AC
diagnostic:
51997([
100,
{
1: [32768, 32769, 32770],
157: [118, 164],
184: {156: 166, 206: 178, 208: 3851559041},
186: {156: 160, 168: h'75820020'},
190: 170,
192: {
156: 108,
214: 4,
224: 230,
226: h'7AB7C2E56B49E2CCE62184CE26818E15A8B173164401B5D3BB93FFD6D2B5EB8F6AC0971502AE3DD49D17EC66528164034C912685B8111BC04CDC9EC13DBADD91CC',
228: 172
}
}
])
운전면허증 CBOR-LD를 base64url로 인코딩하고 그 결과를 'ZZ' 서브파일의 'ZZA' 필드에 있는 PDF417 바이트에 삽입한다.
bytes(@\n\x1e\rANSI 000000090002DL00410234ZZ02750202DLDAQF987654321\nDCSSMITH\nDDEN\nDACJOHN\nDDFN\nDADNONE\nDDGN\nDCAC\nDCBNONE\nDCDNONE\nDBD01012024\nDBB04191988\nDBA04192030\nDBC1\nDAU069 IN\nDAYBRO\nDAG123 MAIN ST\nDAIANYVILLE\nDAJUTO\nDAKF87P20000 \nDCFUTODOCDISCRIM\nDCGUTO\nDAW158\nDCK1234567890\nDDAN\rZZZZA2csdghhkpgGDGYAAGYABGYACGJ2CGHYYpBi4oxicGKYYzhiyGNAa5ZIggRi6ohicGKAYqER1ggAgGL4YqhjApRicGGwY1gQY4BjmGOJYQXq3wuVrSeLM5iGEziaBjhWosXMWRAG107uT/9bSteuPasCXFQKuPdSdF+xmUoFkA0yRJoW4ERvATNyewT263ZHMGOQYrA==\r)
이제 위 내용을 바코드로 변환할 수 있다.
이제 검증을 위해 역과정을 적용한다.
먼저 PDF417에서 데이터를 읽는다.
bytes(@\n\x1e\rANSI 000000090002DL00410234ZZ02750202DLDAQF987654321\nDCSSMITH\nDDEN\nDACJOHN\nDDFN\nDADNONE\nDDGN\nDCAC\nDCBNONE\nDCDNONE\nDBD01012024\nDBB04191988\nDBA04192030\nDBC1\nDAU069 IN\nDAYBRO\nDAG123 MAIN ST\nDAIANYVILLE\nDAJUTO\nDAKF87P20000 \nDCFUTODOCDISCRIM\nDCGUTO\nDAW158\nDCK1234567890\nDDAN\rZZZZA2csdghhkpgGDGYAAGYABGYACGJ2CGHYYpBi4oxicGKYYzhiyGNAa5ZIggRi6ohicGKAYqER1ggAgGL4YqhjApRicGGwY1gQY4BjmGOJYQXq3wuVrSeLM5iGEziaBjhWosXMWRAG107uT_9bSteuPasCXFQKuPdSdF-xmUoFkA0yRJoW4ERvATNyewT263ZHMGOQYrA==\r)
'ZZ' 서브파일의 'ZZA' 필드에 있는 데이터를 추출하고 base 인코딩을 되돌린다.
D9CB1D821864A60183198000198001198002189D82187618A418B8A3189C18A618CE18B218D01AE592208118BAA2189C18A018A8447582002018BE18AA18C0A5189C186C18D60418E018E618E258417AB7C2E56B49E2CCE62184CE26818E15A8B173164401B5D3BB93FFD6D2B5EB8F6AC0971502AE3DD49D17EC66528164034C912685B8111BC04CDC9EC13DBADD91CC18E418AC
이제 검증할 원래 JSON-LD VC를 얻기 위해 CBOR-LD로 압축을 해제한다.
여기서도 매개변수는 CBOR-LD 레지스트리 항목 100과 연결된다.
typeTable:
{
"context":
{
"https://www.w3.org/ns/credentials/v2": 32768,
"https://w3id.org/vc-barcodes/v1": 32769,
"https://w3id.org/utopia/v2": 32770
},
"https://w3id.org/security#cryptosuiteString":
{
"ecdsa-rdfc-2019": 1,
"ecdsa-sd-2023": 2,
"eddsa-rdfc-2022": 3,
"ecdsa-xi-2023": 4
}
}
컨텍스트를 처리하고 컨텍스트 용어에 정수 값을 할당한 결과로 생성되어야 하는 ID-to-term 매핑은 다음과 같다. 이는 압축 중에 구성된 맵의 역이라는 점에 유의한다.
Map(97) {
0 => '@context',
2 => '@type',
4 => '@id',
6 => '@value',
8 => '@direction',
10 => '@graph',
12 => '@included',
14 => '@index',
16 => '@json',
18 => '@language',
20 => '@list',
22 => '@nest',
24 => '@reverse',
26 => '@base',
28 => '@container',
30 => '@default',
32 => '@embed',
34 => '@explicit',
36 => '@none',
38 => '@omitDefault',
40 => '@prefix',
42 => '@preserve',
44 => '@protected',
46 => '@requireAll',
48 => '@set',
50 => '@version',
52 => '@vocab',
100 => '...',
102 => 'BitstringStatusList',
104 => 'BitstringStatusListCredential',
106 => 'BitstringStatusListEntry',
108 => 'DataIntegrityProof',
110 => 'EnvelopedVerifiableCredential',
112 => 'EnvelopedVerifiablePresentation',
114 => 'JsonSchema',
116 => 'JsonSchemaCredential',
118 => 'VerifiableCredential',
120 => 'VerifiablePresentation',
122 => '_sd',
124 => '_sd_alg',
126 => 'aud',
128 => 'cnf',
130 => 'description',
132 => 'digestMultibase',
134 => 'digestSRI',
136 => 'exp',
138 => 'iat',
140 => 'id',
142 => 'iss',
144 => 'jku',
146 => 'kid',
148 => 'mediaType',
150 => 'name',
152 => 'nbf',
154 => 'sub',
156 => 'type',
158 => 'x5u',
160 => 'AamvaDriversLicenseScannableInformation',
162 => 'MachineReadableZone',
164 => 'OpticalBarcodeCredential',
166 => 'TerseBitstringStatusListEntry',
168 => 'protectedComponentIndex',
170 => 'did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj',
172 => 'did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj#zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj',
174 => 'did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj',
176 => 'did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj#zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj',
178 => 'https://sandbox.platform.veres.dev/statuses/z19rJ4oGrbFCqf3cNTVDHSbNd/status-lists',
180 => 'confidenceMethod',
182 => 'credentialSchema',
184 => 'credentialStatus',
186 => 'credentialSubject',
188 => 'evidence',
190 => 'issuer',
192 => 'proof',
194 => 'refreshService',
196 => 'relatedResource',
198 => 'renderMethod',
200 => 'termsOfUse',
202 => 'validFrom',
204 => 'validUntil',
206 => 'terseStatusListBaseUrl',
208 => 'terseStatusListIndex',
210 => 'challenge',
212 => 'created',
214 => 'cryptosuite',
216 => 'domain',
218 => 'expires',
220 => 'nonce',
222 => 'previousProof',
224 => 'proofPurpose',
226 => 'proofValue',
228 => 'verificationMethod',
230 => 'assertionMethod',
232 => 'authentication',
234 => 'capabilityDelegation',
236 => 'capabilityInvocation',
238 => 'keyAgreement'
}
위 내용에 대한 자세한 정보는 6.3 구현 참고사항을 참조한다.
그런 다음 압축 해제는 다음 자격 증명을 생성한다.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/vc-barcodes/v1",
"https://w3id.org/utopia/v2"
],
"type": [
"VerifiableCredential",
"OpticalBarcodeCredential"
],
"credentialSubject": {
"type": "AamvaDriversLicenseScannableInformation",
"protectedComponentIndex": "uggAg"
},
"issuer": "did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj",
"credentialStatus": {
"type": "TerseBitstringStatusListEntry",
"terseStatusListBaseUrl": "https://sandbox.platform.veres.dev/statuses/z19rJ4oGrbFCqf3cNTVDHSbNd/status-lists",
"terseStatusListIndex": 3851559041
},
"proof": {
"type": "DataIntegrityProof",
"verificationMethod": "did:key:zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj#zDnaeWjKfs1ob9QcgasjYSPEMkwq31hmvSAWPVAgnrt1e9GKj",
"cryptosuite": "ecdsa-xi-2023",
"proofPurpose": "assertionMethod",
"proofValue": "z4g6G3dAZhhtPxPWgFvkiRv7krtCaeJxjokvL46fchAFCXEY3FeX2vn46MDgBaw779g1E1jswZJxxreZDCrtHg2qH"
}
}
스캔된 PDF417과 protectedComponentIndex를 입력으로 사용하여
ecdsa-xi-2023이 요구하는 opticalDataBytes를 생성하기 위해
3.2.4.4
opticalDataBytes 생성을 적용한다.
canonicalizedData = 'DACJOHN\nDAQ987654321\nDCSSMITH\n' opticalDataBytes: [188, 38, 200, 146, 227, 213, 90, 250, 50, 18, 126, 254, 47, 177, 91, 23, 64, 129, 104, 223, 136, 81, 116, 67, 136, 125, 137, 165, 117, 63, 152, 207]
그런 다음 자격 증명을 검증하기 위해 3.2.4.3 해싱(ecdsa-xi-2023) 및 3.2.4.2 증명 검증(ecdsa-xi-2023)을 적용한다.
마지막 단계는 운전면허증 자격 증명의 상태 정보를 확인하는 것이다.
TerseBitstringStatusListEntry를 BitstringStatusListEntry로
변환하기 위해 3.2.3 상태
목록 항목 변환을 적용한다.
여기서는 'revocation' 및 'suspension'이라는 두 상태 타입을 확인하며,
해당 문자열들을 statusPurpose의 값으로 전달한다.
{
type: 'BitstringStatusListEntry',
statusListCredential: 'https://sandbox.platform.veres.dev/statuses/z19rJ4oGrbFCqf3cNTVDHSbNd/status-lists/revocation/29385',
statusListIndex: 8321,
statusPurpose: 'revocation'
}
{
type: 'BitstringStatusListEntry',
statusListCredential: 'https://sandbox.platform.veres.dev/statuses/z19rJ4oGrbFCqf3cNTVDHSbNd/status-lists/suspension/29385',
statusListIndex: 8321,
statusPurpose: 'suspension'
}
그런 다음 이는 Bitstring Status List v1.0: Validate Algorithm에서처럼 검증될 수 있다.
컨텍스트 용어에서 CBOR-LD 정수로의 맵을 만들 때, 일부 컨텍스트는 특정 타입의 객체 아래에 중첩된 다른 컨텍스트를 그 안에 포함한다는 점에 유의한다. 이러한 중첩 컨텍스트는 “type-scoped contexts”라고 하며, 연결된 타입이 데이터에서 사용될 때에만 활성화된다. 이는 term ID 할당에 중요하다. 컨텍스트의 용어는 해당 컨텍스트가 활성화된 뒤에야 ID를 한 번만 할당받기 때문이다. 이러한 테스트 벡터에서 Driver's License와 Employment Authorization Document를 위해 생성된 맵이, 두 자격 증명이 동일한 컨텍스트를 사용함에도 서로 다른 이유가 바로 이것이다.
또한 CBOR-LD에서는 연결된 값이 복수일 때 용어를 표현하기 위해 홀수가 사용된다는 점에 유의한다. 예를 들어 위의 CBOR-LD term-to-ID 및 ID-to-term 맵에서 "type"은 156에 매핑되지만, 하나의 VC에서 여러 타입이 표현되는 곳에서는 대신 157이 사용된다.
appContextMap: [['https://www.w3.org/ns/credentials/v2', 32768], ['https://w3id.org/vc-barcodes/v1', 32769], ['https://w3id.org/utopia/v2', 32770]]
이 절은 비규범이다.
이 절에는 시간이 지나면서 이 명세에 이루어진 실질적인 변경 사항이 포함된다.
이 명세의 내용은 표준 트랙 절차가 시작된 후 채워질 예정이다.