규제 상황: eIDAS 1.0에서 eIDAS 2.0까지

규정 에이다스 1.0 (EU 910/2014)은 유럽 연합에서 디지털 신원 시스템의 상호 운용성을 위한 기반을 마련했습니다. 그러나 회원국의 자발적 채택, 모바일 세계에 적합하지 않은 SAML 2.0 흐름, 디지털 지갑의 부재 등 명백한 한계를 보여주었습니다. 시민을 위해 표준화되었습니다. 10년 후, 규정 EU 2024/1183 — 공식적으로 eIDAS 2.0으로 알려짐 —이 발효되었습니다. 는 2024년 5월 20일 게임의 규칙을 다시 작성합니다.

개발자에게 가장 관련성이 높은 소식은 다음과 같습니다. 모든 회원국이 유럽 ​​연합 디지털 신원 지갑(EUDI 지갑) 2026년까지 도입 전자 속성 증명(EAA), 개념 QEAA(적격 전자 속성 증명), 규제 부문의 신뢰 당사자(RP)가 2027년까지 지갑을 수락할 의무가 있습니다.

eIDAS 2.0 규제 일정

  • 2024년 5월 20일 – EU 규정 2024/1183 발효
  • 2025년 – 기술 시행법(ARF, 프로토콜) 발행
  • 2026년 – 모든 EU 국가는 시민에게 EUDI 지갑을 제공해야 합니다.
  • 2027년 – EUDI Wallet을 수락할 의무가 있는 규제 부문의 신뢰 당사자

EUDI 지갑 아키텍처: 기본 구성 요소

EUDI 지갑의 참조 아키텍처는 다음과 같이 정의됩니다.ARF(아키텍처 및 참조 프레임워크), 기술 문서 유럽연합 집행위원회가 관리합니다. 시스템은 네 가지 주요 계층으로 구성됩니다.

1. 발급자 계층 - 자격 증명을 발급하는 사람

그만큼 발행자 검증 가능한 인증서를 발급할 권한이 있는 기관입니다. 두 가지 주요 카테고리가 있습니다:

  • PID 제공자: 국가에서 발행한 기본 신원 증명인 개인 식별 데이터(PID)를 발급합니다(디지털 신원 문서와 동일).
  • 증명 제공자: 운전 면허증, 교육 자격, 건강 카드, 전문 자격 등 EAA(전자 속성 증명)를 발급합니다.

발행을 위한 표준 프로토콜은 다음과 같습니다. OpenID4VCI (검증가능한 자격증명 발급을 위한 OpenID), 전용 엔드포인트로 OAuth 2.0 흐름을 확장합니다. 자격 증명을 요청하고 발급합니다.

// Esempio: Token Request per OpenID4VCI
// POST /token

{
  "grant_type": "urn:ietf:params:oauth:grant-type:pre-authorized_code",
  "pre-authorized_code": "SplxlOBeZQQYbYS6WxSbIA",
  "user_pin": "493536"
}

// Risposta con Access Token
{
  "access_token": "eyJraWQiOiJrZXktMSJ9...",
  "token_type": "bearer",
  "expires_in": 86400,
  "c_nonce": "tZignsnFbp",
  "c_nonce_expires_in": 86400
}

// Credential Request
// POST /credential
// Authorization: Bearer eyJraWQiOiJrZXktMSJ9...

{
  "format": "vc+sd-jwt",
  "credential_definition": {
    "type": ["VerifiableCredential", "PersonIdentificationData"]
  },
  "proof": {
    "proof_type": "jwt",
    "jwt": "eyJraWQiOiJrZXktMiIsInR5cCI6Im9wZW5pZDR2Y2ktcHJvb2Yrand..."
  }
}

2. 지갑 레이어 - 시민의 지갑

Il EUDI 지갑 시민이 자격 증명을 수신, 저장 및 제시하는 데 사용하는 애플리케이션(모바일 또는 웹)입니다. 시행법(EUCC - EU Cybersecurity Certification Scheme for Common Criteria)에서 정의한 보안 표준에 따라 인증을 받아야 합니다. 주요 기능은 다음과 같습니다:

  • 안전한 암호화 키 관리(가능한 경우 하드웨어 지원)
  • SD-JWT VC(선택적 공개 JWT 검증 가능한 자격 증명) 지원
  • 모바일 운전면허증 프로필에 대한 ISO 18013-5(mdoc) 지원
  • NFC/BLE를 통한 근접 프레젠테이션(물리적 제어용)
  • 브라우저를 통한 원격 프레젠테이션(HTTPS 리디렉션)

3. 검증자/신뢰 당사자 계층 - 자격 증명을 받는 사람

I 신뢰 당사자(RP) — VC 생태계에서는 검증자라고도 함 — 인증이 필요한 서비스입니다. 또는 시민의 속성 확인. 제출 프로토콜은 다음과 같습니다. OpenID4VP(검증 가능한 프레젠테이션을 위한 OpenID), 종종 와 함께 사용됩니다. SIOPv2(자체 발급 OpenID 공급자 v2) 자기 주권 흐름의 경우.

4. 신뢰 인프라 - 신뢰의 사슬

EUDI 지갑은 다음을 기반으로 합니다. 유럽 ​​공개 키 인프라(PKI). 위원회가 조정합니다. 각 발급자를 등록해야 합니다. 에서EUDIW 신뢰할 수 있는 발급자 등록소, 검증자는 신뢰 당사자로 등록해야 합니다. 자격 증명 확인이 발생합니다. 회원국의 국가 PKI에 고정된 X.509 v3 인증서를 통해 발급자의 디지털 서명을 확인합니다.

SD-JWT: 선택적 공개 및 개인정보 보호

eIDAS 2.0의 가장 관련성이 높은 기술적 측면 중 하나는 SD-JWT(선택적 공개 JSON 웹 토큰), 정의됨 해당 IETF RFC에서. 기본 아이디어는 보유자가 특정 거래에 필요한 속성만 공개할 수 있도록 하는 것입니다. 전체 신분증을 노출하지 않고.

데이터 최소화 원칙

SD-JWT를 사용하면 시민은 정확한 생년월일을 밝히지 않고도 자신이 성인임을 증명할 수 있습니다. 또는 귀하가 특정 지방 자치 단체에 거주하고 있음을 입증하십시오. 전체 주소를 표시합니다. 이것이 GDPR 원칙의 핵심입니다 데이터 최소화 디지털 ID에 적용됩니다.

SD-JWT는 세 부분으로 구성됩니다.

// Struttura SD-JWT

// 1. JWT Header + Payload (con disclosures hashate)
{
  "iss": "https://issuer.example.gov.it",
  "sub": "user_12345",
  "iat": 1710000000,
  "exp": 1741536000,
  "_sd_alg": "sha-256",
  "_sd": [
    "YIk1uXcv7d9yT8rX4mZ1aA",   // hash di "given_name": "Mario"
    "kp3uX9vZ2d8rT7yX5mZ3bB",   // hash di "family_name": "Rossi"
    "Xp4uX8vZ3d9rT6yX6mZ4cC",   // hash di "birthdate": "1990-01-15"
    "Zp5uX7vZ4d0rT5yX7mZ5dD"    // hash di "age_over_18": true
  ]
}

// 2. Disclosure (payload completo, trasmesso separatamente)
// Ogni disclosure = base64url( salt || claim_name || claim_value )
// Esempio decoded:
["ynMvKGiQegTHCXkHkEL4aA", "given_name", "Mario"]
["qRpTaSvVlGnb9uOtCiKqGg", "age_over_18", true]

// 3. Presentazione selettiva al Verifier
// Il holder invia solo le disclosures che vuole rivelare
// In questo esempio: solo age_over_18, non given_name

eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJodHRwcz...~qRpTaSvVlGnb9uOtCiKqGg~

신뢰 당사자 EUDI 지갑 구현

EUDI Wallet ID를 수락해야 하는 디지털 서비스를 개발하는 경우 검증인/신뢰당사자. 주요 단계는 다음과 같습니다.

1단계: 신뢰 당사자로 등록

각 RP는 중개자 국가 등록부에 등록하고 X.509 인증서를 얻어야 합니다. 이 인증서는 서명에 사용됩니다. 승인 요청 지갑으로 보냈습니다. 이탈리아에서는 등록 기관이 관리합니다. AgID.

2단계: 승인 요청 생성(OpenID4VP)

// Authorization Request OpenID4VP
// Il RP genera un signed JWT con i parametri di presentazione

// Header JWT del Request Object
{
  "alg": "ES256",
  "kid": "rp-key-2025",
  "typ": "oauth-authz-req+jwt"
}

// Payload JWT del Request Object
{
  "client_id": "https://my-service.comune.it/eudi-rp",
  "client_id_scheme": "x509_san_uri",
  "response_type": "vp_token",
  "response_mode": "direct_post",
  "response_uri": "https://my-service.comune.it/eudi-rp/callback",
  "nonce": "n-0S6_WzA2Mj",
  "state": "af0ifjsldkj",
  "presentation_definition": {
    "id": "pid-age-verification",
    "input_descriptors": [
      {
        "id": "pid_vc",
        "format": {
          "vc+sd-jwt": {
            "alg": ["ES256", "ES384"]
          }
        },
        "constraints": {
          "fields": [
            {
              "path": ["$.vct"],
              "filter": {
                "type": "string",
                "const": "PersonIdentificationData"
              }
            },
            {
              "path": ["$.age_over_18"],
              "intent_to_retain": false
            }
          ]
        }
      }
    ]
  }
}

3단계: VP 토큰 확인

지갑이 다음과 같이 응답하면 vp_token, 신뢰 당사자는 다음 확인을 수행해야 합니다.

// Pseudo-codice Python per verifica VP Token

import jwt
import hashlib
import base64

def verify_vp_token(vp_token: str, expected_nonce: str) -> dict:
    # 1. Splitta SD-JWT in parti (~ come separatore)
    parts = vp_token.split("~")
    sd_jwt = parts[0]
    disclosures = parts[1:-1]  # ultime parte potrebbe essere KB-JWT
    key_binding_jwt = parts[-1] if len(parts) > 1 else None

    # 2. Decodifica e verifica il JWT principale
    header = jwt.get_unverified_header(sd_jwt)
    # Recupera il certificato dell'issuer dalla PKI europea
    issuer_cert = fetch_issuer_cert(header.get("x5c"))
    payload = jwt.decode(sd_jwt, issuer_cert, algorithms=["ES256"])

    # 3. Verifica nonce nel Key Binding JWT
    if key_binding_jwt:
        kb_payload = jwt.decode(key_binding_jwt, options={"verify_signature": False})
        assert kb_payload["nonce"] == expected_nonce, "Nonce mismatch"
        assert kb_payload["aud"] == "https://my-service.comune.it/eudi-rp"

    # 4. Risolvi le disclosures
    disclosed_claims = {}
    for disclosure in disclosures:
        # Verifica hash
        disclosure_hash = base64.urlsafe_b64encode(
            hashlib.sha256(disclosure.encode()).digest()
        ).rstrip(b"=").decode()
        if disclosure_hash in payload.get("_sd", []):
            decoded = json.loads(base64.urlsafe_b64decode(disclosure + "=="))
            # formato: [salt, claim_name, claim_value]
            disclosed_claims[decoded[1]] = decoded[2]

    return disclosed_claims

IT Wallet Italiano: 최신 기술

이탈리아는 자체적인 방법을 통해 EUDI Wallet 생태계에 접근하고 있습니다. IT 지갑, 2024년 7월 3일 입법령에 ​​의해 제공됨 n. 31 및 개발 PNRR 내에서. 시스템은 다음에 의해 운영됩니다. PagoPA S.p.A. 기존 SPID 및 CIE(전자 신분증) 시스템을 통합합니다.

IT Wallet은 EUDI 준수 Wallet을 향한 전환 솔루션으로 설계되었으며 2025년 초부터 파일럿 단계를 시작했습니다. 디지털 운전 면허증, 건강 카드 및 장애인 수첩을 첫 번째 자격 증명으로 사용할 수 있습니다.

IT 지갑 자격 증명(파일럿 단계 2025)

  • mDL – 모바일 운전 면허증 (ISO 18013-5)
  • TS-CNS – 건강 카드 / 국가 서비스 카드
  • 장애증명서 – INPS 인증
  • PID – 개인 식별 데이터(CIE에서 파생)

SIOPv2를 사용하는 OpenID4VP: 장치 간 흐름

일반적인 시나리오는 교차 장치 흐름: 사용자가 데스크톱에서 웹사이트를 방문하고 스마트폰을 이용해 지갑으로 인증합니다. 일반적인 흐름에서는 QR 코드를 초기 통신 채널로 사용합니다.

// Flusso cross-device EUDI Wallet

// 1. Il RP genera il Request Object e lo rende disponibile
GET /eudi/request.jwt HTTP/1.1
// Risposta: signed JWT con presentation_definition

// 2. Il RP mostra un QR code che contiene:
eudi-openid4vp://?
  client_id=https%3A%2F%2Fmy-service.comune.it%2Feudi-rp&
  request_uri=https%3A%2F%2Fmy-service.comune.it%2Feudi-rp%2Frequest.jwt&
  state=af0ifjsldkj

// 3. Il wallet dell'utente scansiona il QR:
//    - Risolve il request_uri
//    - Valida la firma del Request Object
//    - Mostra all'utente quale attributo viene richiesto
//    - Chiede il consenso

// 4. Il wallet invia la risposta via direct_post al response_uri:
POST /eudi-rp/callback HTTP/1.1
Content-Type: application/x-www-form-urlencoded

vp_token=eyJhbGciOiJFUzI1NiJ9...&
state=af0ifjsldkj

// 5. Il RP verifica la VP Token
// 6. Il RP redirige il browser desktop tramite session polling o SSE

SPID 및 CIE와의 상호 운용성

이탈리아 개발자는 현재 시스템이 새로운 EUDI 생태계와 어떻게 공존하는지 이해해야 합니다.

체계 규약 신원 만료 메모
SPID SAML 2.0 / OIDC 페더레이션(비공개 IdP) 2026년 이상까지 운영 점차적으로 EUDI로 수렴될 것입니다.
CIE(전자 신분증) SAML 2.0 / OIDC / NFC 주(내무부) 장기 운영 EUDI 지갑의 PID 소스
IT월렛(PagoPA) 오픈ID4VCI / 오픈ID4VP 국민지갑 2025+ (파일럿) EUDI 지갑으로 전환
EUDI 지갑 OpenID4VCI / OpenID4VP / SD-JWT EU(국경 간) 2026년부터 의무화 확실한 유럽 표준

보안 및 암호화 고려 사항

EUDI 지갑을 구현하려면 여러 보안 측면에 주의가 필요합니다.

키 바인딩

각 자격 증명은 다음과 같은 메커니즘을 통해 암호화 방식으로 지갑(따라서 시민의 물리적 장치)에 연결됩니다. 키 바인딩. 소유자의 개인 키는 장치의 보안 요소를 벗어나면 안 됩니다. 그만큼 키 바인딩 JWT(KB-JWT) 발표자가 SD-JWT에 등록된 공개키에 해당하는 개인키를 소유하고 있음을 증명합니다.

재생공격 방지

분야 nonce 승인 요청에서는 RP에 의해 무작위로 생성되며 지갑에서 서명한 KB-JWT에 포함되어야 합니다. RP는 nonce가 원래 생성된 nonce와 일치하는지 확인하여 재생 공격을 방지합니다.

경고: 시간적 타당성

검증가능한 크리덴셜은 만료일(exp). 서비스는 자격 증명이 만료되지 않았는지 항상 확인해야 합니다. (현행법에 정의된 상태 목록 또는 OCSP 유사 메커니즘을 통해) 철회 정책을 고려합니다.

인증서 유효성 검사

발급자 인증서는 유럽 트러스트 앵커까지 PKI 체인을 따라 검증되어야 합니다. 항상 업데이트된 버전을 사용하세요 의 신뢰할 수 있는 목록 유럽 ​​연합(EU 위원회의 API를 통해 사용 가능)

개발자 도구 및 라이브러리

EUDI Wallet을 중심으로 한 오픈 소스 생태계는 빠르게 성장하고 있습니다. 가장 중요한 참고자료는 다음과 같습니다.

# Librerie ufficiali EU (reference implementations)

# Python - EUDI Wallet Issuer SDK
pip install eudi-srv-pid-issuer

# Python - SD-JWT Reference Implementation
pip install sd-jwt

# Java - EUDI Wallet Core Library
# gradle dependency:
# implementation("eu.europa.ec.eudi:eudi-lib-jvm-sdjwt-kt:latest")

# TypeScript/JavaScript
npm install @sd-jwt/sd-jwt-vc @sd-jwt/decode
npm install openid4vc  # OID4VCI + OID4VP client

# --- Esempio uso sd-jwt in TypeScript ---
import { SDJwtVcInstance } from "@sd-jwt/sd-jwt-vc";
import { digest, generateSalt } from "@sd-jwt/crypto-nodejs";

const sdjwt = new SDJwtVcInstance({
  signer: async (data: string) => sign(data, issuerPrivateKey),
  signAlg: "ES256",
  verifier: async (data: string, sig: string) => verify(data, sig, issuerPublicKey),
  hasher: digest,
  hashAlg: "sha-256",
  saltGenerator: generateSalt,
});

// Emetti una credenziale
const credential = await sdjwt.issue(
  {
    iss: "https://issuer.gov.it",
    iat: Math.floor(Date.now() / 1000),
    vct: "PersonIdentificationData",
    given_name: "Mario",
    family_name: "Rossi",
    age_over_18: true,
    birthdate: "1990-01-15",
  },
  // Indica quali claim sono selectively disclosable
  {
    _sd: ["given_name", "family_name", "birthdate", "age_over_18"],
  }
);

console.log(credential); // eyJhbGciOiJFUzI1NiJ9...~...

테스트 및 샌드박스 환경

프로덕션으로 이동하기 전에 공식 샌드박스 환경을 사용하세요.

  • EU EUDI 지갑 참조 애플리케이션: GitHub(eu-digital-identity-wallet)에서 오픈 소스 Android/iOS 앱으로 사용할 수 있습니다. 발급자 데모, 검증자 데모 및 PID 발급자 테스트가 포함됩니다.
  • 이탈리아 IT 지갑 샌드박스: PagoPA는 Relying Party(연락처) 등 통합을 위한 테스트 환경을 제공합니다. 개발자.italia.it 커뮤니티에서 액세스하세요).
  • EUDIW 적합성 테스트 도구: 시행법 준수 여부를 테스트하기 위한 EU 위원회 도구입니다.

이탈리아 개발자를 위한 로드맵

공공 행정 기관이나 이탈리아 시민에게 서비스를 제공하는 민간 회사에 근무하는 경우 구체적인 조치는 다음과 같습니다. 앞으로 몇 달 안에 수행할 작업:

EUDI 지갑 준비 체크리스트

  • 인증 전략 업데이트: 지금 OpenID4VP와 SPID/CIE OIDC를 결합하세요.
  • 연구하다 프리젠테이션 정의 사용 사례에 맞게(어떤 속성이 실제로 필요합니까?)
  • 백엔드 애플리케이션에 SD-JWT 확인 구현
  • 가능한 경우 AgID 등록부에 서비스를 신뢰 당사자로 등록하십시오.
  • EUDI 지갑 참조 앱(GitHub의 Android 버전)과 테스트 통합
  • VC 맥락에서 GDPR 및 데이터 최소화에 대해 팀 교육
  • 시행법 모니터링: 기술 사양은 2026년까지 발전합니다.

결론

eIDAS 2.0과 EUDI Wallet은 최근 수십 년 동안 유럽 디지털 신원 환경의 가장 근본적인 변화를 나타냅니다. 개발자에게 이는 SD-JWT, OpenID4VCI, OpenID4VP, SIOPv2 및 대륙 전체 PKI와 같은 완전히 새로운 기술 생태계를 수용하는 것을 의미합니다.

전환은 즉각적이지 않습니다. SPID와 CIE는 수년 동안 계속해서 병렬로 작동할 예정입니다. 그러나 이제 준비를 시작할 시간입니다. 조기에 적응하는 서비스는 실질적인 경쟁 우위를 갖게 되며 EUDI 지갑의 대량 채택이 변화할 때 준비될 것입니다. 개인 정보 보호, 통제 및 국경 간 상호 운용성 측면에서 사용자 기대.

GovTech 시리즈는 계속됩니다

시리즈의 다음 기사에서 정부 ID용 OpenID Connect 구현에 대해 자세히 알아보세요.