'JWK'에 해당되는 글 1건

  1. 2023.11.14 JWKS uri를 이용한 JWK 검증에 대해 1
웹3 세상에서는 개인이 identity와 data에 대한 통제권을 갖습니다.
그래서 웹3 세상을 열기 위해서는 identity와 data 관리에 대한 고민이 필수적입니다.
그런 맥락에서 현실 세계의 대표적인 identity 관리 방식인 OAuth2와 OpenID Connect을 살펴봅니다.

 

OAuth2 표준과 OpenID Connect 표준

  • OAuth2는 Authorization(이후 authZ)에 대한 표준이다.
  • 반면 OpenID Connect(이후 OIDC)는 Authentication(이후 authN)에 대한 표준이다.
  • OIDC 표준은 OAuth2 표준을 기반으로 정의되었다.

 

OIDC AuthZ code flow

그림1. OAuth2 시퀀스 그림2. OIDC 시퀀스
  • 그림1은 OAuth2 authZ code grant type의 동작 시퀀스다.
  • 그림2는 OIDC authZ code flow의 동작 시퀀스다.
  • 두 시퀀스는 사실상 동일하다. 두 시퀀스의 차이점은 id-provider 서버(그림의 'KEYCLOAK')로부터 받아 오는 토큰이다(양쪽 그림의 5번 'Exchange authZ code...' 화살표).
    • 이때 OAuth2 프로토콜은 Access Token을 발급하고, OIDC 프로토콜은 ID Token을 발급한다.

 

OIDC JWT 표준

  • ID Token의 규격은 OIDC 표준이 정한다.
    • ID Token은 JWT(JSON Web Token) 포맷을 따른다.
  • JWT 토큰에는 토큰 발급자(issuer, 이후 iss)의 priv-key를 이용해서 만든 서명이 포함되어 있어서, 누구나 iss의 pub-key를 이용해서 토큰의 무결성을 검증할 수 있다.
  • Access Token 관련해서는 정해진 규격이 없다.
    • OAuth2 표준은 Access Token의 포맷을 규정하지 않는다. 그래서 어떤 포맷을 사용하더라도 표준에 부합한다.
    • Access Token 포맷으로 JWT를 사용하는 경우가 많다.
  • 관련용어
    • JWT: JSON Web Token
    • JWS: JSON Web Signature
    • JWKS: JSON Web Key Set

 

JWT 토큰 검증

https://jwt.io

https://jwt.io 페이지에서 JWT 포맷으로 발급된 토큰을 검증할 수 있다.

  1. 로컬머신에 OIDC id-provider 서버를 띄우고 JWT 포맷의 Access Token을 발급 받는다.
  2. 발급 받은 토큰을 https://jwt.io/ 에 Copy & Paste 한다.
  3. "Signature Verified" 문구를 확인할 수 있다.
토큰샘플 eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtlT0tCZGNNdVNGcnhWU0dTZlhBcFNmLXlYR3BRMEFmQmx1YnU4OVJ1R1kifQ.eyJleHAiOjE2OTk1OTY3NjQsImlhdCI6MTY5OTUxMDM2NCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MzgwIiwic3ViIjoidGVzdC1hY2Nlc3MifQ.psH3-wi6cztRaVaXe0Exh9Aoo_qkvB7_UQhcs1Kzlk8zcLpOZrb20-BLJPs8cV4vlr1jkpm2E_q-cHfAq41ged48zRp0O3bwEPekTinE2T1qfKG3t_8WJu80Wn5Q4d64P8xQCPA8Ly_Q-Q8pRzdmjQBeUK9jZxzEmeqa9BGadna1IHM-WBd7LzCq5pCjS9gkphIy9t5J_bW2f6Nhp67T-VY9gneNy8izTgrja_ulXtifPqHZNaAK7IFFpyJxCvM__3RMOeEFuHYmtmGN7_pT2gT9QJ5cYwGRFbox2V1q95dUfLQWn0nQmC7l1VxOKBRMGcSgGtvvMBu8x-nPalY3gw
JWT 검증OK

잠깐, 뭘로 검증했지?

  • JWT 토큰에 포함된 Signature는 iss의 priv-key를 이용해 만들어진 값이다.
  • 이를 검증하려면 iss의 pub-key가 필요하다.
  • 그런데 JWT 토큰 안에는 iss의 pub-key가 존재하지 않는다. 어디서 가져왔을까?

JWKS URI

JWT 토큰을 검증하려면 iss의 pub-key를 확보해야 한다. 그 절차는 다음과 같다.

  1. 토큰에 포함된 iss 속성값으로부터 well-known URL을 유추한다 (iss + '/.well-known/openid-configuration').
  2. (예시로 든 토큰샘플의 iss는 http://localhost:8380 이다. 이 토큰을 검증해서 Signature Verified 결과를 얻으려면 http://localhost:8380/.well-known/openid-configuration 엔드포인트를 호스팅하는 id-provider가 떠 있어야 한다.)
  3. well-known URL에서 JWKS uri를 확보한다.
  4. JWKS uri에서 iss의 pub-key를 얻을 수 있다.

http://localhost:8380/.well-known/openid-configuration 엔드포인트의 응답

{
  "issuer": "http://localhost:8380",
  "authorization_endpoint": "http://localhost:8380/authz",
  "token_endpoint": "http://localhost:8380/token",
  "userinfo_endpoint": "http://localhost:8380/userinfo",
  "jwks_uri": "http://localhost:8380/jwks"
}

 

http://localhost:8380/jwks 엔드포인트의 응답

{
  "keys": [
    {
      "kty": "RSA",
      "kid": "keOKBdc...",
      "use": "sig",
      "alg": "RS256",
      "e": "AQAB",
      "n": "xPyyJCGj..."
    }
  ]
}

 

Ref

Keycloak Identity and Access Management for Modern Applications (2nd Ed.) 책

Understanding ID Token

How do you choose between OAuth2 and OpenID Connect for web authorization?

JWKs and node-jose

Validate an OpenID Connect JWT using a public key in JWKS

What is OIDC Discovery .well-known end-point?

 

Posted by ingeeC
,