검증 가능한 자격 증명 바코드 v1.0

광학 바코드에 Verifiable Credentials 삽입하기

W3C 작업 초안

이 문서에 대한 더 자세한 정보
이 버전:
https://www.w3.org/TR/2026/WD-vc-barcodes-1.0-20260623/
최신 공개 버전:
https://www.w3.org/TR/vc-barcodes-1.0/
최신 편집자 초안:
https://w3c.github.io/vc-barcodes/
이력:
https://www.w3.org/standards/history/vc-barcodes-1.0/
커밋 이력
편집자:
Wesley Smith (Digital Bazaar)
Elaine Wooton (초청 전문가)
Manu Sporny (Digital Bazaar)
저자:
Manu Sporny (Digital Bazaar)
Dave Longley (Digital Bazaar)
Wesley Smith (Digital Bazaar)
피드백:
GitHub w3c/vc-barcodes (풀 리퀘스트, 새 이슈, 미해결 이슈)
관련 명세
검증 가능한 자격 증명 데이터 모델 v2.0
검증 가능한 자격 증명 데이터 무결성 v1.1
타원 곡선 디지털 서명 알고리즘 암호 스위트 v1.1
Linked Data를 위한 간결한 이진 객체 표현 v1.0

초록

이 명세는 운전면허증(PDF417) 및 여행 문서(MRZ)에서 볼 수 있는 것과 같은 광학 바코드를 Verifiable Credentials [VC-DATA-MODEL-2.0]를 사용하여 보호하는 메커니즘을 설명한다. Verifiable Credential 표현은 150바이트 미만에 들어갈 만큼 충분히 압축되어 있으므로 표준 인쇄 공정을 사용해 물리적 카드에 인쇄되는 기존의 2차원 바코드와 통합될 수 있다.

이 문서의 상태

이 절은 이 문서가 발행된 시점의 상태를 설명한다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있다.

이 문서는 Verifiable Credentials Working GroupRecommendation 트랙을 사용하여 작업 초안으로 발행했다.

작업 초안으로서의 발행은 W3C 및 그 회원의 승인을 의미하지 않는다.

이는 초안 문서이며 언제든지 다른 문서에 의해 업데이트, 대체 또는 폐기될 수 있다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않다.

이 문서는 W3C Patent Policy에 따라 운영되는 그룹에 의해 작성되었다. W3C는 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지하며, 해당 페이지에는 특허 공개를 위한 지침도 포함되어 있다. 어떤 개인이 자신이 보유한 실제 지식에 근거하여 어떤 특허가 Essential Claim(s)을 포함한다고 믿는 경우, 그 개인은 W3C Patent Policy 제6절에 따라 정보를 공개해야 한다.

이 문서는 2025년 8월 18일 W3C Process Document의 적용을 받는다.

1. 소개

운전면허증, 여권, 여행 자격 증명과 같은 물리적 자격 증명에는 문서에서 정보를 빠르게 읽는 데 사용할 수 있는 기계 판독 가능 데이터가 포함되는 경우가 많다. 이 정보는 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를 바코드별로 폐기하거나 정지할 수 있다.

1.1 입문 예제

다음 절에서는 이 명세를 사용해 검증 가능한 자격 증명을 통한 디지털 서명으로 기존의 물리적 자격 증명을 향상할 수 있는 몇 가지 입문 예제를 제공한다.

1.1.1 운전면허증

이 절에서는 이 명세의 기술을 사용하여 PDF417 바코드를 사용하는 운전면허증의 광학 바코드를 보호하는 방법에 대한 예를 제공한다. 예제 운전면허증으로 시작한다.

Utopia 주에서 발급한 운전면허증 앞면 그림. 운전면허증의 대상자인 개인의 사진과 이름, 주소, 신장, 체중, 눈 색상, 운전 권한과 같은 속성이 포함되어 있다.
그림 1 Utopia 주에서 발급한 운전면허증의 앞면.

운전면허증의 뒷면에는 PDF417 바코드가 포함되어 있다.

Utopia 주에서 발급한 운전면허증 뒷면 그림. 사용 규칙과 카드 앞면에 표시된 정보의 상당 부분을 인코딩하는 PDF417 바코드가 포함되어 있다.
그림 2 Utopia 주에서 발급한 운전면허증의 뒷면.

PDF417 데이터에는 이 명세에서 설명하는 알고리즘을 사용해 보호되는 정보가 포함되어 있다. 즉, PDF417 바코드에는 다음 형식의 검증 가능한 자격 증명이 포함된다.

예제 1: PDF417 바코드에 삽입된 Verifiable Credential
{
  "@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).

예제 2: CBOR-LD로 압축된 Verifiable Credential(145 바이트)
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
  }
}

1.1.2 고용 허가

이 절에서는 이 명세의 기술을 사용하여 카드 뒷면에 기계 판독 가능 영역(MRZ)을 사용하는 고용 허가 문서의 기계 판독 가능 영역을 보호하는 방법에 대한 예를 제공한다. 예제 고용 허가 문서로 시작한다.

Utopia 주에서 발급한 고용 허가 문서 앞면 그림. 문서의 대상자인 개인의 사진과 이름, 주소, 신장, 체중, 눈 색상, 고용 권한과 같은 속성이 포함되어 있다.
그림 3 Utopia 주에서 발급한 고용 허가 문서의 앞면.

고용 허가 문서의 뒷면에는 광학 문자 인식을 통해 읽히도록 설계된 정보를 포함하는 기계 판독 가능 영역(MRZ)이 있다.

Utopia 주에서 발급한 고용 허가 문서 뒷면 그림. 사용 규칙과 카드 앞면에 표시된 정보의 상당 부분을 인코딩하는 기계 판독 가능 영역 데이터가 포함되어 있다.
그림 4 Utopia 주에서 발급한 고용 허가 문서의 뒷면.

MRZ 데이터에는 이 명세에서 설명하는 알고리즘을 사용해 보호되는 정보가 포함되어 있다. 즉, 카드 앞면의 QR Code에는 카드 뒷면의 정보를 보호하는 다음 형식의 검증 가능한 자격 증명이 포함되어 있다.

예제 3: 카드 앞면의 QR Code로 표현된 Verifiable Credential
{
  "@context": [
    "https://www.w3.org/ns/credentials/v2",
    "https://w3id.org/citizenship/v2",
    "https://w3id.org/citizenship/utopia/v1"
  ],
  "type": [
    "VerifiableCredential",
    "OpticalBarcodeCredential"
  ],
  // 아래 값은 위의 'utopia/v1' 컨텍스트에서 URL로 정의된다
  "issuer": "did:web:immigration.utopia.example",
  "credentialSubject": {
    "type": "MachineReadableZone",
  },
  "proof": {
    "type": "DataIntegrity",
    "cryptosuite": "ecdsa-xi-2023",
    // 아래 값은 위의 'utopia/v1' 컨텍스트에서 URL로 정의된다
    "verificationMethod": "did:web:immigration.utopia.example#key-4"
    "proofPurpose": "assertionMethod",
    "proofValue": "z4peo48uwK2EF4Fta8P...HzQMDYJ34r9gL"
  }
}
참고: credentialStatus는 선택 사항이다

독자는 위의 자격 증명에 선택 사항인 credentialStatus 속성이 포함되어 있지 않다는 점을 알아차릴 수 있다. 모든 광학 바코드 자격 증명 발급자가 폐기 가능한 광학 바코드 자격 증명을 가져야 하는 요구사항을 갖는 것은 아니다.

위의 검증 가능한 자격 증명은 그런 다음 [CBOR-LD]를 사용해 다음 출력으로 압축된다(CBOR Diagnostic Notation).

예제 4: CBOR-LD로 압축된 Verifiable Credential(120 바이트)
{
  1 => [ 32768, 32769, 32770],           // @context
  155 => [ 116, 176 ],                   // type
  208 => 194,                          // issuer
  204 => { 154 => 192 },                 // credentialSubject
  210 => {                               // proof
    154 => 108,                          // type
    226 => 4,                        // cryptosuite
    236 => 242                         // verificationMethod
    240 => 196,                          // proofPurpose
    210 => Uint8Array(65) [ ... ],       // proofValue
  }
}

1.1.3 출생증명서

이 절에서는 이 명세의 기술을 사용하여 출생증명서를 검증 가능한 자격 증명으로 보호하고, 이를 인쇄된 종이 문서 위의 QR Code로 표현하는 방법에 대한 예를 제공한다.

신생아의 이름, 부모 이름, 병원에 관한 정보, 참석자, 등록 책임자와 같은 정보가 포함된 출생증명서 앞면 그림.
그림 5 Utopia 주의 한 병원에서 발급한 출생증명서의 앞면.

QR Code는 다음 검증 가능한 자격 증명을 인코딩한다. 인코딩의 세부 사항은 아래의 별도 탭에서 확인할 수 있다.

예제 5: 약식 출생증명서를 표현하는 검증 가능한 자격 증명
{
  "@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"
      }]
    }
  }
}
application/vc+cborld

d9cb1d8201a60182782468747470733a2f2f7777772e77332e6f72672f6e732f63726564656e7469616c732f7632782468747470733a2f2f773369642e6f72672f766974616c2d7265636f7264732f7631726331189d82187618a4190130a3189c18a218cc74323032332d30392d33305431333a34343a35325a190104a618966754696d20446f65189c18ae18bc74323032332d31302d30355431343a32393a30305a18c4a6189c18b21901446655746f7069611901466b55746f70696120546f776e1901486855746f706f6c697319014a65313233343519014c6f31323320486f73706974616c20526418e2644d616c6519010b82a31896684a616e6520446f65189c18ac1901026a4a616e6520536d697468a21896684a6f686e20446f65189c18aa190134820277686f73706974616c2e6578616d706c652f697373756572190136a6189c186c1901501a6a3abdd71901526f65636473612d726466632d3230313919015c19016219015e58417ae780156acdf39b8a76dd9dfdcc7d9cf32636e91579f894a2f1fc8cafc9fd0fb5a72660ed343f1ca88542eafd94e542c509080ab479da5e303fb74dcdd20656741901608219040158238024035ecd0dd569e4db7f6feefdb0249d9156db32899632ae707466310043e3cb954b1901401a651806b8

JSON-LD 크기: 1037바이트
CBOR-LD 크기: 484바이트
압축률 : 53%

application/vc
{
  "@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"
  }
}
            

CBOR-LD Diagnostic Mode
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
    }
  ])}
            
image/png

Verifiable Credential QR Code
QR Code 버전: 15
오류 정정: 낮음

QR Code 내용(텍스트)
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
            

JSON-LD Diagnostic Mode
{
  "@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"
  }
}}
            

1.2 설계 목표

다음은 이 명세의 기술에 대한 설계 목표이다.

1.3 용어

이 문서 전체에서 사용되는 용어는 Verifiable Credentials Data Model v2.0 명세의 용어 절과 Verifiable Credential Data Integrity 1.0 명세에 정의되어 있다.

Unicode code point order
이는 [XPATH-FUNCTIONS]에 정의된 대로 Unicode Codepoint Collation을 사용하여 두 Unicode 문자열(AB)의 순서를 결정하는 것을 말한다. 이 정의는 코드 포인트를 비교하는 문자열전순서를 정의한다. UTF-8로 인코딩된 문자열의 경우 바이트 시퀀스를 비교하면 코드 포인트 순서와 동일한 결과가 나온다는 점에 유의한다.

1.4 적합성

비규범으로 표시된 절뿐만 아니라, 이 명세의 모든 작성 지침, 도표, 예제, 참고는 비규범이다. 이 명세의 그 밖의 모든 것은 규범이다.

이 문서에서 핵심어 MAY, MUST, RECOMMENDED, REQUIRED, 및 SHOULD는 여기 표시된 것처럼 모두 대문자로 나타나는 경우에 한해서 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석되어야 한다.

적합 문서는 이 명세의 규범적 진술을 준수하는 데이터 모델의 모든 구체적 표현이다. 구체적으로 이 문서의 2. 데이터 모델3. 알고리즘 절의 모든 관련 규범적 진술은 MUST 시행되어야 한다.

적합 프로세서적합 문서를 생성하거나 소비하는 소프트웨어 및/또는 하드웨어로 실현된 모든 알고리즘이다. 적합 프로세서는 비적합 문서를 소비할 때 오류를 생성해야 MUST 한다.

이 문서에는 JSON 및 JSON-LD 데이터 예제가 포함되어 있다. 이러한 예제 중 일부는 인라인 주석(//)처럼 특정 부분을 설명하는 기능과 예제와 관련 없는 정보의 생략을 나타내는 줄임표(...)를 포함하므로 유효하지 않은 JSON이다. 구현자가 예제를 유효한 JSON 또는 JSON-LD로 취급하려는 경우 이러한 부분은 제거해야 한다.

2. 데이터 모델

다음 절들은 이 명세가 바코드 및 여행 문서의 기계 판독 가능 영역과 같은 광학적으로 인쇄된 정보를 보호하는 검증 가능한 자격 증명을 표현하는 데 사용하는 데이터 모델을 개괄한다.

2.1 OpticalBarcodeCredential

OpticalBarcodeCredential은 광학 바코드의 내용을 보호하는 데 사용되며, 1) 작성자 정보, 2) 변조 방지성, 3) 선택적으로 폐기 및 정지 상태를 제공한다. 다시 말해, 이 자격 증명은 광학 바코드를 누가 발급했는지, 광학 바코드가 처음 발급된 이후 변조되었는지, 그리고 광학 바코드의 발급자가 문서가 여전히 유효한지 여부를 아직 보증하는지를 알려줄 수 있다. 이러한 기능은 물리적 문서에 대해 상당한 사기 방지 보호를 제공한다.

OpticalBarcodeCredentialcredentialSubjectAamvaDriversLicenseScannableInformation 또는 MachineReadableZone 타입 중 하나이다. AamvaDriversLicenseScannableInformation검증 가능한 자격 증명이 물리적 문서의 PDF417 바코드와 검증 가능한 자격 증명에 표현된 정보를 보호한다는 것을 의미한다. MachineReadableZone검증 가능한 자격 증명이 물리적 문서의 기계 판독 가능 영역과 검증 가능한 자격 증명에 표현된 정보를 보호한다는 것을 의미한다.

OpticalBarcodeCredentialAamvaDriversLicenseScannableInformation 타입인 경우, 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 생성을 참조한다.

가능한 한 높은 압축률을 달성하기 위해, issuerverificationMethod 필드는 JSON-LD Context의 용어를 활용하는 것이 RECOMMENDED되며, 그러면 CBOR-LD의 의미 기반 압축 메커니즘 덕분에 몇 바이트 수준으로 압축될 수 있다.

이 절에 지정된 속성을 활용하는 광학 바코드 자격 증명의 예는 아래와 같다.

예제 6: TerseBitstringStatusListEntry를 활용하는 OpticalBarcodeCredential
{
  "@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"
  }
}

2.2 TerseBitstringStatusListEntry

TerseBitstringStatusListEntryBitstring Status List v1.0 명세에 정의된 BitstringStatusListEntry의 간결한 표현이다.

TerseBitstringStatusListEntry 타입의 객체는 두 개의 추가 속성을 가져야 MUST 한다.

TerseBitstringStatusListEntry를 처리하려면, Section 3.2.3 상태 목록 항목 변환의 알고리즘을 적용하여 이를 BitstringStatusListEntry로 변환한 다음, Bitstring Status List v1.0에서처럼 처리한다.

구현자는 개별 상태 목록의 길이에 대해 listLength 값을 설정해야 한다. 그러면 32비트 terseStatusListIndex에 대해 상태 목록 수 listCount = 2^32 / listLength가 산출된다. listLengthTerseBitstringStatusListEntryBitstringStatusListEntry로 변환하는 데 필요하다. listLength의 일부 값은 이러한 상태 목록의 개인정보 보호 속성을 해칠 수 있다는 점에 유의하여, 구현은 listLength = 2^26 및 listCount = 2^6을 사용해야 MUST 한다.

2.3 바코드로 인코딩 및 바코드에서 디코딩

이 명세의 자격 증명은 CBOR-LD를 사용하여 검증 가능한 자격 증명을 이진 형식으로 효율적으로 인코딩하지만, 이진 데이터는 표준 바코드 이미지 형식으로 직접 변환하기에 비효율적이거나 호환되지 않는 경우가 많다. 이를 위해 여기서는 구현에 대한 요구사항을 제공한다.

구현자가 CBOR-LD로 인코딩된 AamvaDriversLicenseScannableInformation 자격 증명을 PDF417에 인코딩하기 전에 base64url로 문자 인코딩하는 것이 RECOMMENDED된다. 멀티베이스 헤더는 base로 인코딩된 VCB 데이터 앞에 붙일 수 MAY 있다. PDF417 필드 헤더 명세는 멀티베이스 헤더가 있는지 없는지를 나타낼 것으로 예상된다.

구현자가 CBOR-LD로 인코딩된 MachineReadableZone 자격 증명을 QR 코드에 인코딩하기 전에 문자열 'VC1-'를 앞에 붙인 base45-multibase로 다시 인코딩하는 것이 REQUIRED된다.

3. 알고리즘

다음 절은 운전면허증 및 여행 문서와 같은 물리 매체의 바코드 및 기계 판독 가능 영역과 같은 광학 정보를 보호하는 디지털 증명을 추가하고 검증하기 위한 알고리즘을 설명한다.

3.1 일반 알고리즘

이 절에는 검증 가능한 자격 증명의 인코딩 및 디코딩에 일반적으로 적용되는 알고리즘이 포함된다.

3.1.1 CBOR-LD 압축 테이블

이 명세는 검증 가능한 자격 증명을 인코딩하고 디코딩할 때 애플리케이션별 압축 테이블을 CBOR-LD 프로세서에 제공할 것을 요구한다. 다양한 발급자에 대한 모든 컨텍스트 URL의 레지스트리는 쉼표로 구분된 값 파일로 제공되며, 추가 전용 및 선착순 방식으로 해당 파일에 대한 변경 요청을 통해 업데이트하고 수정할 수 있다. 구현은 압축 및 압축 해제가 최신 값을 지원하도록 보장하기 위해 매월 최신 파일을 가져와 활용해야 SHOULD 한다.

3.1.2 VC를 QR Code로 인코딩

다음 알고리즘은 검증 가능한 자격 증명을 QR Code로 표현할 수 있는 텍스트 문자열로 인코딩하는 방법을 지정한다. 필수 입력은 검증 가능한 자격 증명(map inputDocument)과 옵션 집합 (map options)이다. 출력은 인코딩된 검증 가능한 자격 증명 (string) 또는 오류이다. 이 알고리즘이 문자열을 인코딩할 때마다 UTF-8 인코딩을 사용해야 MUST 한다.

  1. typeTableoptions.typeTable의 값으로 둔다.
  2. registryEntryIdoptions.registryEntryId의 값으로 둔다.
  3. inputDocument, typeTable, registryEntryId를 입력으로 전달하여 JSON-LD to CBOR-LD Encoding Algorithm을 수행한 결과를 cborldDocument로 둔다. 인코딩 오류가 발생하면 오류가 발생되어야 MUST 한다.
  4. cborldDocumentbytes로, 정수 45targetBase로, 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:baseAlphabet로 전달하여 Base Encoding 알고리즘을 수행한 결과를 base45Value로 둔다.
  5. 다음 값들을 연결한 결과를 qrCodeText로 둔다. VC1-, R(base45의 Multibase 접두사), 및 base45Value.
  6. qrCodeText를 인코딩된 검증 가능한 자격 증명으로 반환한다. 이는 이후 QR Code 이미지로 인코딩할 텍스트로 임의의 QR Code 라이브러리에 제공될 수 있다.

3.1.3 QR Code를 VC로 디코딩

다음 알고리즘은 QR Code로 인코딩된 검증 가능한 자격 증명을 디코딩하는 방법을 지정한다. 필수 입력은 텍스트 문자열(string inputDocument)과 옵션 집합(map options)이다. 출력은 검증 가능한 자격 증명(map) 또는 오류이다. 이 알고리즘이 문자열을 인코딩할 때마다 UTF-8 인코딩을 사용해야 MUST 한다.

  1. inputDocument가 텍스트 VC1-R로 시작하는지 확인한다. 그렇지 않으면 오류가 발생되어야 MUST 한다.
  2. inputDocument에서 처음 다섯 문자(VC1-R)를 제거한 것을 base45Value로 둔다.
  3. base45ValuesourceEncoding으로, 정수 45sourceBase로, 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:baseAlphabet로 전달하여 Base Decoding 알고리즘을 수행한 결과를 cborldDocument로 둔다.
  4. cborldDocument를 입력으로 전달하여 CBOR-LD to JSON-LD Decoding Algorithm을 수행한 결과를 jsonldDocument로 둔다. 디코딩 오류가 발생하면 오류가 발생되어야 MUST 한다.
  5. jsonldDocument를 디코딩된 검증 가능한 자격 증명으로 반환한다.

3.2 OpticalBarcodeCredential 알고리즘

이 절에는 typeOpticalBarcodeCredential검증 가능한 자격 증명의 인코딩 및 디코딩에 특화된 알고리즘이 포함된다.

3.2.1 OpticalBarcodeCredential 인코딩

  1. opticalData를 보호할 광학 바코드의 데이터로 설정한다.
  2. statusListEntryVerbose를 발급자가 OpticalBarcodeCredential에 추가하려는 BitstringStatusListCredential (Bitstring Status List v1.0 명세에 정의된 것)으로 설정한다.
  3. statusListEntryTerse를 빈 map으로 둔다. statusListEntryTerse.typeTerseBitstringStatusListEntry로 설정하고, statusListEntryTerse.indexstatusListEntryVerbose.statusListIndex의 정수 표현으로 설정한다.
  4. issuerUrl을 발급자가 자격 증명 검증에 사용하려는 URL로 설정한다.
  5. unsignedStatusunsignedStatus.issuerissuerUrl로 설정되고, unsignedStatus.credentialStatusstatusListEntryTerse로 설정된 OpticalBarcodeCredential로 설정한다.
  6. 3.2.4.1 증명 추가 (ecdsa-xi-2023)의 알고리즘을 사용하여 opticalDataunsignedStatus에 서명한 결과를 signedStatusVc로 설정한다.
  7. signedStatusVc를 CBOR-LD [CBOR-LD]를 사용해 인코딩하고, 이를 opticalData의 지정된 영역에 추가한다.
  8. 기계 판독 가능 자격 증명(MRZ 또는 PDF417)을 생성한다.

3.2.2 OpticalBarcodeCredential 디코딩

  1. securedDocument를 PDF417 또는 MRZ의 데이터로 설정한다.
  2. Section 3.2.4.2 증명 검증(ecdsa-xi-2023)의 알고리즘을 securedDocument에 적용한 결과를 verificationResult로 설정한다.
  3. credentialsecuredDocument 안의 OpticalBarcodeCredential로 설정한다.
  4. Section 3.2.3 상태 목록 항목 변환의 알고리즘을 credential에 적용한 결과를 statusListEntry로 설정한다.
  5. Bitstring Status List v1.0: Validate AlgorithmstatusListEntry에 적용한 결과를 statusResult로 설정한다.
  6. (validationResult, statusResult)를 반환한다.

3.2.3 상태 목록 항목 변환

이 절의 알고리즘은 TerseBitstringStatusListEntryBitstringStatusListEntry로 변환하는 데 사용된다. 이는 검증 가능한 자격 증명에 대한 검증이 수행된 후, 유효성 검사 과정에서 사용된다.

검증 가능한 자격 증명 검증이 수행된 후, 이 알고리즘은 OpticalBarcodeCredential 검증 가능한 자격 증명 (struct vc), vc와 연결된 BitstringStatusListCredential의 항목 수를 포함하는 정수 listLength, 그리고 문자열 statusPurpose(예: 'revocation', 'suspension'...)를 입력으로 받아 'BitstringStatusListEntry' 객체를 반환한다.

  1. result를 빈 map으로 설정한다.
  2. listIndexvc.credentialStatus.terseStatusListIndex/listLength를 내림하여 다음으로 낮은 정수로 만든 값 (즉, floor() 연산 적용)으로 설정한다.
  3. statusListIndexvc.credentialStatus.terseStatusListIndex % listLength로 설정한다.
  4. result.statusListCredential을 다음 값들을 연결한 것으로 설정한다. vc.credentialStatus.terseStatusListBaseUrl, '/', statusPurpose, '/', listIndex.
  5. result.type을 'BitstringStatusListEntry'로 설정한다.
  6. result.statusListIndexstatusListIndex로 설정한다.
  7. result.statusPurposestatusPurpose로 설정한다.
  8. result를 반환한다.

resultBitstring Status List v1.0 명세의 유효성 검사 알고리즘에 대한 입력으로 사용할 수 있다.

참고: 상태 목록은 선택 사항이다

구현자는 모든 발급자가 자신의 검증 가능한 자격 증명에 대한 상태 목록 정보를 게시하지는 않는다는 점에 유의해야 한다. 일부 발급자검증자가 상태 목록 자격 증명에 접근하도록 허용하기 전에 권한 부여를 요구할 수 있다.

3.2.4 ecdsa-xi-2023

ecdsa-xi-2023 cryptosuite는 사실상 ecdsa-rdfc-2019 알고리즘 [VC-DI-ECDSA]에 원래 광학 바코드 데이터와 같은 일부 “extra information”(xi)을 입력으로 받아 그 데이터를 디지털 서명으로 보호되는 정보에 포함하는 단계를 추가한 것이다. 이 절의 알고리즘은 이러한 서명이 어떻게 생성되고 검증되는지 자세히 설명한다.

3.2.4.1 증명 추가 (ecdsa-xi-2023)

증명을 생성하려면 Data Integrity [VC-DATA-INTEGRITY] 명세의 Section 4.1: Add Proof에 있는 알고리즘을 실행해야 MUST 한다. 해당 알고리즘에 대해, cryptographic suite specific transformation algorithmData Integrity ECDSA Cryptosuites v1.0 Transformation (ecdsa-rdfc-2019) 절에 정의되고, hashing algorithm은 Section 3.2.4.3 해싱 (ecdsa-xi-2023)에 정의되며, proof serialization algorithmData Integrity ECDSA Cryptosuites v1.0 Proof Serialization (ecdsa-rdfc-2019) 절에 정의된다.

3.2.4.2 증명 검증 (ecdsa-xi-2023)

증명을 검증하려면 Data Integrity [VC-DATA-INTEGRITY] 명세의 Section 4.2: Verify Proof에 있는 알고리즘을 실행해야 MUST 한다. 해당 알고리즘에 대해, cryptographic suite specific transformation algorithmData Integrity ECDSA Cryptosuites v1.0 Transformation (ecdsa-rdfc-2019) 절에 정의되고, hashing algorithm은 Section 3.2.4.3 해싱(ecdsa-xi-2023)에 정의되며, proof verification algorithmData Integrity ECDSA Cryptosuites v1.0 Proof Verification (ecdsa-rdfc-2019) 절에 정의된다.

3.2.4.3 해싱(ecdsa-xi-2023)

해싱 알고리즘은 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단계를 다음 두 단계로 대체한다.

  1. hashData에 적용된 것과 동일한 해시 알고리즘을 opticalDataBytes 값에 적용한 결과를 opticalDataHash로 둔다.
  2. proofConfigHash(첫 번째 해시), transformedDocumentHash(두 번째 해시), 그리고 opticalDataHash(세 번째 해시)를 결합한 결과를 hashData로 둔다.
3.2.4.4 opticalDataBytes 생성
AamvaDriversLicenseScannableInformation 자격 증명
  1. dataToCanonicalize를 빈 배열로 설정한다.
  2. credentialSubject.protectedComponentIndex를 multibase-base64url에서 이진으로 디코딩한 결과인 길이 24비트 bitstring의 처음 22비트를 bitfieldDecoded로 설정한다.
  3. Unicode 코드 포인트 순서로 정렬된 22개의 AAMVA 필수 PDF417 Element ID [aamva-dl-id-card-design-standard] (즉, ['DAC', 'DAD' ... 'DDG'])를 포함하는 배열을 fieldsAlphabetized로 설정한다.
  4. bitfieldDecoded에서 값이 1인 각 비트에 대해:
    1. 문자열 fieldNamefieldsAlphabetized[i]로 설정한다. 여기서 ibitfieldDecoded 안에서 해당 비트의 인덱스이다.
    2. 문자열 fieldData를 해당 필드 이름과 연결된 PDF417에 들어갈 데이터로 설정한다.
    3. fieldDatafieldName 끝에 연결하고, 줄바꿈 문자 (\n, U+000A)를 끝에 연결한 다음, 그 결과를 dataToCanonicalize에 추가한다.
  5. dataToCanonicalize를 Unicode 코드 포인트 순서로 정렬한 다음, 배열에서 단일 문자열을 생성하기 위해 join 연산을 적용한 결과를 canonicalizedData로 설정한다.
  6. canonicalizedData를 해시하고 그 결과를 반환한다.
MachineReadableZone 자격 증명
  1. dataToCanonicalize를 빈 배열로 설정한다.
  2. 자격 증명의 Machine Readable Zone에 있는 각 줄에 대해:
    1. mrzLine을 해당 줄의 데이터를 포함하는 문자열로 설정한다.
    2. 줄바꿈 문자를 mrzLine 끝에 추가하고 mrzLinedataToCanonicalize에 추가한다.
  3. dataToCanonicalize의 요소들을 자격 증명에 나타나는 순서와 일치하도록 정렬한 다음, 배열에서 단일 문자열을 생성하기 위해 join 연산을 적용한 결과를 canonicalizedData로 설정한다.
  4. canonicalizedData를 해시하고 그 결과를 반환한다.
3.2.4.5 증명 구성(ecdsa-xi-2023)

증명 구성 알고리즘은 Data Integrity ECDSA Cryptosuites v1.0 Proof Configuration (ecdsa-rdfc-2019) 절에 정의된 것이며, 4단계를 다음 단계로 대체한다.

  1. options.typeDataIntegrityProof로 설정되어 있지 않고 proofConfig.cryptosuiteecdsa-xi-2023으로 설정되어 있지 않으면, INVALID_PROOF_CONFIGURATION 오류가 발생되어야 MUST 한다.

4. 보안 고려사항

이 절은 비규범이다.

이 절을 읽기 전에 독자는 Data Integrity 명세의 보안 고려사항 절에서 제공하는 일반적인 보안 조언과 ECDSA Cryptosuites 명세의 보안 고려사항 절에서 제공하는 구체적인 보안 조언을 숙지할 것을 권장한다.

다음 절들에서는 이러한 중요한 사항들을 검토하고 독자를 추가 정보로 안내한다.

4.1 광학 데이터 중복

OpticalBarcodeCredentials에 대한 한 공격 벡터는 디지털 서명이 포함된 광학 바코드를 복제하여 위조 문서에 사용하는 것이다. 복제된 바코드는 원본처럼 서명 검증을 통과하지만, 이 공격은 문서 검증자가 다음 세 가지를 확인함으로써 완화된다. 서명된 데이터가 문서에 보이는 데이터와 일치하는지, 서명된 데이터가 사용자의 물리적 속성과 일치하는지, 그리고 보이는 데이터가 사용자의 물리적 속성과 일치하는지이다. 이 세 가지가 모두 동일할 때, OpticalBarcodeCredential이 중복일 수 있는 유일한 경우는 위조 문서 작성자가 위조 문서 사용자의 물리적 속성과 서명된 물리적 속성이 완전히 겹치는 실제 OpticalBarcodeCredential에 접근할 수 있었던 경우이다. 임의의 사람의 외형과 완전히 일치하는 도난된 OpticalBarcodeCredential이 탐지되지 않은 채 존재할 가능성이 낮기 때문에, 이 공격은 성공하기 어렵다.

4.2 부분적으로 서명된 광학 데이터

어떤 경우에는 기존 광학 데이터 전체에 대해 디지털 서명을 생성할 수 없을 수도 있다. 예를 들어 물리적 자격 증명 제조업체가 일련번호를 삽입하여 서명 시점에는 발급자가 이를 알 수 없는 경우를 고려한다. 이 경우 검증자는 디지털 서명되지 않은 모든 데이터가 OpticalBarcodeCredential의 성공적인 검증 능력에 영향을 주지 않고 광학 바코드에서 변경되었을 수 있다고 가정한다.

광학 바코드의 데이터가 문서에 보이는 데이터 및 문서 소지자의 특성과 일치하는지 확인할 때, 구현자는 디지털 서명된 필드만 사용할 것을 권장한다. 검증자는 다른 필드가 서명되지 않은 문서의 사기 탐지에 얼마나 흔히 사용되는지와 관계없이, 디지털 서명으로 보호되는 필드만 사용할 것을 권장한다. 예를 들어 눈 색상과 머리카락 색상이 서명으로 보호되지만 소지자의 초상은 그렇지 않은 경우, 검증자는 초상보다 눈 색상과 머리카락 색상에 중점을 두어 사기 탐지를 시도할 것을 권장한다.

검증자가 사용하는 소프트웨어의 구현자는 검증 과정에서 디지털 서명으로 보호된 카드 데이터만 표시할 것을 권장한다. 변조되었을 수 있는 서명되지 않은 데이터를 표시하면 사기 탐지를 방해할 수 있다.

4.3 안전한 검증

검증자OpticalBarcodeCredential의 유효성을 확인하기 위해 항상 신뢰할 수 있는 프로그램과 인터페이스를 사용할 것을 권장한다. 신뢰할 수 없는 소프트웨어를 사용해 문서를 검증하면 위조 자격 증명이 수락되거나 진짜 자격 증명이 도난당할 수 있다.

5. 개인정보 보호 고려사항

이 절을 읽기 전에 독자는 Data Integrity 명세의 보안 고려사항 절에서 제공하는 일반적인 보안 조언과 ECDSA Cryptosuites 명세의 보안 고려사항 절에서 제공하는 구체적인 보안 조언을 숙지할 것을 권장한다.

다음 절은 이 명세를 구현하는 개발자가 개인정보 보호 가정을 위반하지 않기 위해 알고 있어야 하는 개인정보 보호 고려사항을 설명한다.

이슈 1
최소한 다음 내용을 포함하여 개인정보 보호 고려사항을 더 추가한다.
  • 바코드는 거리에서 읽힐 수 있다. 따라서 매우 민감한 정보는 바코드에 인코딩하지 않는 것이 좋으며, NFC 또는 암호화된 온라인 통신 채널을 통해 전송하는 것이 더 나을 수 있다.

6. 테스트 벡터

이 절은 비규범이다.

이 절에는 Verifiable Credential Barcodes의 예와 함께, 그것들이 어떻게 생성되고 어떻게 검증되는지에 대한 단계별 과정이 포함되어 있다.

이 절에서는 두 가지 실행 예제를 분석한다. Utopia Employment Authorization Document의 MRZ를 보호하는 VCB와 Utopia Driver's License의 PDF417을 보호하는 VCB이다.

6.1 VCB 생성

6.1.1 Utopia 운전면허증

먼저 VCB가 서명할 데이터, 즉 PDF417의 필수 AAMVA 필드로 시작한다.

예제 7: Utopia 운전면허증에 나타날 수 있는 PDF417의 필드
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
6.1.1.1 opticalDataBytes 생성

단순화를 위해, PDF417에서 서명하려는 유일한 데이터가 이름(DAC), 성(DCS), 그리고 면허 번호(DAQ)라고 가정한다. protectedComponentIndex에 사용할 bitstring 값은 100000100000000000100000이고, protectedComponentIndex의 값은 "uggAg"이다. 3.2.4.4 opticalDataBytes 생성을 적용하면 다음을 얻는다.

예제 8: Utopia 운전면허증의 정규화에서 나온 데이터
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에 서명할 수 있다. BitstringStatusListCredential3.2.1 OpticalBarcodeCredential 인코딩을 실행하면 다음 JSON-LD VC를 얻는다.

6.1.1.2 예제 VC
예제 9: Utopia 운전면허증 VCB에 대한 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"
  }
}
6.1.1.3 CBOR-LD 압축 및 인코딩

이제 이 VC에 CBOR-LD 압축을 적용할 수 있다. 여기서는 최신 버전의 CBOR-LD를 사용하지만, 이 절의 끝에서는 최신 상태가 아닌 CBOR-LD 구현과의 상호운용성 테스트를 위해 이전 버전의 CBOR-LD로 인코딩된 VCB도 제공한다.

이 명세를 위해 값 100을 가진 CBOR-LD 레지스트리 항목을 예약했다 (즉, 이러한 페이로드는 태그 0x0664로 시작한다). CBOR-LD를 사용해 인코딩하기 위한 매개변수는 CBOR-LD 명세의 레지스트리에서 찾을 수 있으며, 다음과 같다.

예제 10: 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 매핑은 다음과 같다.

예제 11: Utopia DL을 압축할 때 CBOR-LD가 생성하는 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 구현 참고사항을 참조한다.

그 결과 다음 인코딩된 자격 증명이 생성된다.

예제 12: CBOR-LD로 압축된 Utopia 운전면허증 VC
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 바이트에 삽입한다.

예제 13: 인코딩된 Utopia 운전면허증 VCB를 포함하는 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)

이제 위 내용을 바코드로 변환할 수 있다.

Utopia 운전면허증의 VCB.
그림 6 Utopia 운전면허증의 VCB.

6.1.2 Utopia 고용 허가 문서

먼저 VCB가 서명할 데이터, 즉 MRZ로 시작한다.

예제 14: Utopia EAD에 나타날 수 있는 기계 판독 가능 영역
IAUTO0000007010SRC0000000701<<
8804192M2601058NOT<<<<<<<<<<<5
SMITH<<JOHN<<<<<<<<<<<<<<<<<<<
6.1.2.1 opticalDataBytes 생성

EAD의 경우 3.2.4.4 opticalDataBytes 생성을 적용한다.

예제 15: Utopia EAD MRZ의 정규화에서 나온 데이터
canonicalizedData =
  'IAUTO0000007010SRC0000000701<<\n' +
  '8804192M2601058NOT<<<<<<<<<<<5\n' +
  'SMITH<<JOHN<<<<<<<<<<<<<<<<<<<\n'
opticalDataBytes:
[8, 198, 126, 183,  25, 160, 166, 112,
254, 184, 189,  47, 225, 211, 125, 210,
132, 137, 45,  86, 169,  28,  57, 165,
46, 253, 9, 137, 145,  42, 192, 113]

이제 이 해시 값을 3.2.4.3 해싱 (ecdsa-xi-2023)과 함께 사용하여 VC에 서명할 수 있다. 상태를 추가하지 않고 3.2.1 OpticalBarcodeCredential 인코딩을 실행하면 다음 JSON-LD VC를 얻는다.

6.1.2.2 예제 VC
예제 16: Utopia EAD VCB에 대한 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": "MachineReadableZone"
  },
  "issuer": "did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj",
  "proof": {
    "type": "DataIntegrityProof",
    "verificationMethod": "did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj#zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj",
    "cryptosuite": "ecdsa-xi-2023",
    "proofPurpose": "assertionMethod",
    "proofValue": "z4B8AQgjwgsEdcPEZkrkK2mTVKn7qufoDgDkv9Qitf9tjxQPMoJaGdXwDrThjp7LUdvzsDJ7UwYu6Xpm9fjbo6QnJ"
  }
}
6.1.2.3 CBOR-LD 압축 및 인코딩

이제 이 VC에 CBOR-LD 압축을 적용할 수 있다. 여기서는 최신 버전의 CBOR-LD를 사용하지만, 이 절의 끝에서는 최신 상태가 아닌 CBOR-LD 구현과의 상호운용성 테스트를 위해 이전 버전의 CBOR-LD로 인코딩된 VCB도 제공한다.

이 명세를 위해 값 100을 가진 CBOR-LD 레지스트리 항목을 예약했다 (즉, 이러한 페이로드는 태그 0x0664로 시작한다). CBOR-LD를 사용해 인코딩하기 위한 매개변수는 CBOR-LD 명세의 레지스트리에서 찾을 수 있으며, 다음과 같다.

예제 17: 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 매핑은 다음과 같다.

예제 18: Utopia EAD를 압축할 때 CBOR-LD가 생성하는 term-to-ID 맵
Map(95) {
  '@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,
  'challenge' => 206,
  'created' => 208,
  'cryptosuite' => 210,
  'domain' => 212,
  'expires' => 214,
  'nonce' => 216,
  'previousProof' => 218,
  'proofPurpose' => 220,
  'proofValue' => 222,
  'verificationMethod' => 224,
  'assertionMethod' => 226,
  'authentication' => 228,
  'capabilityDelegation' => 230,
  'capabilityInvocation' => 232,
  'keyAgreement' => 234
}

위 내용에 대한 자세한 정보는 6.3 구현 참고사항을 참조한다.

그런 다음 압축은 다음 인코딩된 자격 증명을 생성한다.

예제 19: CBOR-LD로 압축된 Utopia EAD VC
D9CB1D821864A50183198000198001198002189D82187618A418BAA1189C18A218BE18AE18C0A5189C186C18D20418DC18E218DE58417A9EC7F688F60CAA8C757592250B3F6D6E18419941F186E1ED4245770E687502D51D01CD2C2295E4338178A51A35C2F044A85598E15DB9AEF00261BC5C95A744E718E018B0

diagnostic:
51997([
  100,
  {
    1: [32768, 32769, 32770],
    157: [118, 164],
    186: {156: 162},
    190: 174,
    192: {
      156: 108,
      210: 4,
      220: 226,
      222: h'7A9EC7F688F60CAA8C757592250B3F6D6E18419941F186E1ED4245770E687502D51D01CD2C2295E4338178A51A35C2F044A85598E15DB9AEF00261BC5C95A744E7',
      224: 176
    }
  }
])

EAD CBOR-LD를 base45-multibase로 인코딩하고 'VC1-'를 앞에 붙인다.

예제 20: 인코딩된 Utopia EAD VCB
VC1-R0OR*W3Y33V%K PG88G3A3B60A8G1534KG$-ENXKWQN053653Y53I53 539*K0XJ.TDYOQJ63P63L6337BPMFPCP7EH2R12YH%%EXU4$08E-D8D86F8E2HX:T8Z8/ 1TZEH.QBA03Q5W.I0N6FBF4E3:SOQU8. A3MSELNHFU0GCVVBP6LU9T%ES-3

이제 위 내용을 QR 코드로 변환할 수 있다.

6.1.2.4 고용 허가 문서
Utopia EAD의 VCB.
그림 7 Utopia EAD의 VCB.

다음 MRZ와 함께 사용한다.

Utopia Employment Authorization Document의 MRZ.
그림 8 Utopia Employment Authorization Document의 MRZ.

6.2 VCB 검증

이제 검증을 위해 역과정을 적용한다.

6.2.1 Utopia 운전면허증

6.2.1.1 디코딩 및 압축 해제

먼저 PDF417에서 데이터를 읽는다.

예제 21: 인코딩된 Utopia 운전면허증 VCB를 포함하는 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 인코딩을 되돌린다.

예제 22: CBOR-LD로 압축된 Utopia 운전면허증 VC
D9CB1D821864A60183198000198001198002189D82187618A418B8A3189C18A618CE18B218D01AE592208118BAA2189C18A018A8447582002018BE18AA18C0A5189C186C18D60418E018E618E258417AB7C2E56B49E2CCE62184CE26818E15A8B173164401B5D3BB93FFD6D2B5EB8F6AC0971502AE3DD49D17EC66528164034C912685B8111BC04CDC9EC13DBADD91CC18E418AC

이제 검증할 원래 JSON-LD VC를 얻기 위해 CBOR-LD로 압축을 해제한다. 여기서도 매개변수는 CBOR-LD 레지스트리 항목 100과 연결된다.

예제 23: CBOR-LD 디코딩 매개변수
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 매핑은 다음과 같다. 이는 압축 중에 구성된 맵의 역이라는 점에 유의한다.

예제 24: Utopia DL을 압축 해제할 때 CBOR-LD가 생성하는 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 구현 참고사항을 참조한다.

그런 다음 압축 해제는 다음 자격 증명을 생성한다.

예제 25: Utopia 운전면허증 VCB에 대한 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"
  }
}
6.2.1.2 검증

스캔된 PDF417과 protectedComponentIndex를 입력으로 사용하여 ecdsa-xi-2023이 요구하는 opticalDataBytes를 생성하기 위해 3.2.4.4 opticalDataBytes 생성을 적용한다.

예제 26: Utopia 운전면허증 PDF417의 정규화
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)을 적용한다.

6.2.1.3 상태 확인

마지막 단계는 운전면허증 자격 증명의 상태 정보를 확인하는 것이다. TerseBitstringStatusListEntryBitstringStatusListEntry로 변환하기 위해 3.2.3 상태 목록 항목 변환을 적용한다. 여기서는 'revocation' 및 'suspension'이라는 두 상태 타입을 확인하며, 해당 문자열들을 statusPurpose의 값으로 전달한다.

예제 27: 상태 목적 revocation에 대한 BitstringStatusListEntry
{
  type: 'BitstringStatusListEntry',
  statusListCredential: 'https://sandbox.platform.veres.dev/statuses/z19rJ4oGrbFCqf3cNTVDHSbNd/status-lists/revocation/29385',
  statusListIndex: 8321,
  statusPurpose: 'revocation'
}
예제 28: 상태 목적 suspension에 대한 BitstringStatusListEntry
{
  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에서처럼 검증될 수 있다.

6.2.2 Utopia 고용 허가 문서

6.2.2.1 디코딩 및 압축 해제

먼저 QR 코드에서 데이터를 읽는다.

예제 29: 인코딩된 Utopia Driver's License EAD
VC1-R0OR*W3Y33V%K PG88G3A3B60A8G1534KG$-ENXKWQN053653Y53I53 539*K0XJ.TDYOQJ63P63L6337BPMFPCP7EH2R12YH%%EXU4$08E-D8D86F8E2HX:T8Z8/ 1TZEH.QBA03Q5W.I0N6FBF4E3:SOQU8. A3MSELNHFU0GCVVBP6LU9T%ES-3

'VC1-' 뒤의 데이터를 추출하고 base 인코딩을 되돌린다.

예제 30: CBOR-LD로 압축된 Utopia EAD VC
D9CB1D821864A50183198000198001198002189D82187618A418BAA1189C18A218BE18AE18C0A5189C186C18D20418DC18E218DE58417A9EC7F688F60CAA8C757592250B3F6D6E18419941F186E1ED4245770E687502D51D01CD2C2295E4338178A51A35C2F044A85598E15DB9AEF00261BC5C95A744E718E018B0

이제 검증할 원래 JSON-LD VC를 얻기 위해 CBOR-LD로 압축을 해제한다. 여기서도 매개변수는 CBOR-LD 레지스트리 항목 100과 연결된다.

예제 31: CBOR-LD 디코딩 매개변수
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 매핑은 다음과 같다. 이는 압축 중에 구성된 맵의 역이라는 점에 유의한다.

예제 32: Utopia EAD를 압축 해제할 때 CBOR-LD가 생성하는 ID-to-term 맵
Map(95) {
  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 => 'challenge',
  208 => 'created',
  210 => 'cryptosuite',
  212 => 'domain',
  214 => 'expires',
  216 => 'nonce',
  218 => 'previousProof',
  220 => 'proofPurpose',
  222 => 'proofValue',
  224 => 'verificationMethod',
  226 => 'assertionMethod',
  228 => 'authentication',
  230 => 'capabilityDelegation',
  232 => 'capabilityInvocation',
  234 => 'keyAgreement'
}

위 내용에 대한 자세한 정보는 6.3 구현 참고사항을 참조한다.

그런 다음 압축 해제는 다음 자격 증명을 생성한다.

예제 33: Utopia EAD VCB에 대한 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": "MachineReadableZone"
  },
  "issuer": "did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj",
  "proof": {
    "type": "DataIntegrityProof",
    "verificationMethod": "did:key:zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj#zDnaeZSD9XcuULaS8qmgDUa6TMg2QjF9xABnZK42awDH3BEzj",
    "cryptosuite": "ecdsa-xi-2023",
    "proofPurpose": "assertionMethod",
    "proofValue": "z4B8AQgjwgsEdcPEZkrkK2mTVKn7qufoDgDkv9Qitf9tjxQPMoJaGdXwDrThjp7LUdvzsDJ7UwYu6Xpm9fjbo6QnJ"
  }
}
6.2.2.2 검증

EAD의 MRZ를 입력으로 사용하여 ecdsa-xi-2023이 요구하는 opticalDataBytes를 생성하기 위해 3.2.4.4 opticalDataBytes 생성을 적용한다.

예제 34: Utopia EAD MRZ의 정규화
canonicalizedData =
  'IAUTO0000007010SRC0000000701<<\n' +
  '8804192M2601058NOT<<<<<<<<<<<5\n' +
  'SMITH<<JOHN<<<<<<<<<<<<<<<<<<<\n'
opticalDataBytes:
[8, 198, 126, 183,  25, 160, 166, 112,
254, 184, 189,  47, 225, 211, 125, 210,
132, 137, 45,  86, 169,  28,  57, 165,
46, 253, 9, 137, 145,  42, 192, 113]

그런 다음 자격 증명을 검증하기 위해 3.2.4.3 해싱(ecdsa-xi-2023)3.2.4.2 증명 검증(ecdsa-xi-2023)을 적용한다.

6.3 구현 참고사항

6.3.1 CBOR-LD

컨텍스트 용어에서 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이 사용된다.

6.4 레거시 CBOR-LD 인코딩 자격 증명

이 프로세스는 완전히 최신 상태가 아닌 CBOR-LD 구현이 사용되었는지 테스트하는 데 사용된다.

6.4.1 CBOR-LD 버전 6.X

프로세스는 동일하게 유지되지만, CBOR-LD 디코딩 단계는 예외이며, 이 단계에서는 다음 appContextMap을 사용해야 한다.
예제 35: 상태 목적 suspension에 대한 BitstringStatusListEntry
appContextMap:
[['https://www.w3.org/ns/credentials/v2', 32768],
['https://w3id.org/vc-barcodes/v1', 32769],
['https://w3id.org/utopia/v2', 32770]]
6.4.1.1 Utopia 운전면허증
레거시 CBOR-LD로 인코딩된 Utopia 운전면허증의 VCB.
그림 9 레거시 CBOR-LD로 인코딩된 Utopia 운전면허증의 VCB.
6.4.1.2 Utopia 고용 허가 문서
레거시 CBOR-LD로 인코딩된 Utopia EAD의 VCB.
그림 10 레거시 CBOR-LD로 인코딩된 Utopia EAD의 VCB.

다음 MRZ와 함께 사용한다.

Utopia Employment Authorization Document의 MRZ.
그림 11 Utopia Employment Authorization Document의 MRZ.

6.4.2 CBOR-LD 버전 7.X

6.4.2.1 Utopia 운전면허증
레거시 CBOR-LD로 인코딩된 Utopia 운전면허증의 VCB.
그림 12 레거시 CBOR-LD로 인코딩된 Utopia 운전면허증의 VCB.
6.4.2.2 Utopia 고용 허가 문서
레거시 CBOR-LD로 인코딩된 Utopia EAD의 VCB.
그림 13 레거시 CBOR-LD로 인코딩된 Utopia EAD의 VCB.

다음 MRZ와 함께 사용한다.

Utopia Employment Authorization Document의 MRZ.
그림 14 Utopia Employment Authorization Document의 MRZ.

7. 개정 이력

이 절은 비규범이다.

이 절에는 시간이 지나면서 이 명세에 이루어진 실질적인 변경 사항이 포함된다.

이슈 2: 내용은 표준 트랙이 시작된 후 채워질 예정이다

이 명세의 내용은 표준 트랙 절차가 시작된 후 채워질 예정이다.

A. 참고문헌

A.1 규범 참고문헌

[aamva-dl-id-card-design-standard]
AAMVA DL/ID Card Design Standard (2020). American Association of Motor Vehicle Administrators. 2020. URL: https://www.aamva.org/assets/best-practices,-guides,-standards,-manuals,-whitepapers/aamva-dl-id-card-design-standard-(2020)
[CBOR-LD]
Linked Data를 위한 간결한 이진 객체 표현 v1.0. URL: https://w3c.github.io/cbor-ld/
[CID]
Controlled Identifiers v1.0. Michael Jones; Manu Sporny. W3C. 2025년 5월 15일. W3C Recommendation. URL: https://www.w3.org/TR/cid-1.0/
[ICAO9303-3]
기계 판독 가능 여행 문서 Part 3: 모든 MRTD에 공통되는 명세, 제8판, 2021. ICAO. International Civil Aviation Organization. 2021. URL: https://www.icao.int/publications/Documents/9303_p3_cons_en.pdf
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[ISO15438-2015]
ISO/IEC 15438:2015: PDF417 바코드 심볼로지 명세. ISO/IEC JTC 1/SC 31. International Standards Organization. 2015. URL: https://www.iso.org/standard/65502.html
[RFC2119]
RFC에서 요구 수준을 나타내는 데 사용하는 핵심어. S. Bradner. IETF. 1997년 3월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 핵심어에서 대문자와 소문자의 모호성. B. Leiba. IETF. 2017년 5월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[URL]
URL Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://url.spec.whatwg.org/
[VC-BITSTRING-STATUS-LIST]
Bitstring Status List v1.0. Manu Sporny; Dave Longley; Mahmoud Alkhraishi; Michael Prorock. W3C. 2025년 5월 15일. W3C Recommendation. URL: https://www.w3.org/TR/vc-bitstring-status-list/
[VC-DATA-INTEGRITY]
Verifiable Credential Data Integrity 1.0. Ivan Herman; Manu Sporny; Ted Thibodeau Jr; Dave Longley; Greg Bernstein. W3C. 2025년 5월 15일. W3C Recommendation. URL: https://www.w3.org/TR/vc-data-integrity/
[VC-DATA-MODEL-2.0]
Verifiable Credentials Data Model v2.0. Ivan Herman; Michael Jones; Manu Sporny; Ted Thibodeau Jr; Gabe Cohen. W3C. 2025년 5월 15일. W3C Recommendation. URL: https://www.w3.org/TR/vc-data-model-2.0/
[VC-DI-ECDSA]
Data Integrity ECDSA Cryptosuites v1.0. Manu Sporny; Dave Longley; Greg Bernstein. W3C. 2025년 5월 15일. W3C Recommendation. URL: https://www.w3.org/TR/vc-di-ecdsa/
[XPATH-FUNCTIONS]
XQuery 1.0 및 XPath 2.0 Functions and Operators (제2판). Ashok Malhotra; Jim Melton; Norman Walsh; Michael Kay. W3C. 2010년 12월 14일. W3C Recommendation. URL: https://www.w3.org/TR/xpath-functions/