ログイン中のQiita Team
ログイン中のチームがありません

Qiita Team にログイン
コミュニティ
OrganizationイベントアドベントカレンダーQiitadon (β)
サービス
Qiita JobsQiita ZineQiita Blog
公開鍵
openid_connect
OIDC
9
どのような問題がありますか?

この記事は最終更新日から1年以上が経過しています。

投稿日

更新日

OpenID ConnectのJWTとJWKを手軽につくりたい

OpenID ConnectのJWT(IDトークン)とJWKを、ペイロードの値を色々変えながら作りたいと思って、シェル上で作るスクリプトを作成しました。

必要なツール

  • openssl
  • nodejs
  • jq

結論

#/bin/sh
header='
{
  "kid": "12345",
  "alg": "RS256"
}'
payload='
{
  "iss": "https://example.com",
  "sub": "user-id-123",
  "aud": "client-app-id-123",
  "exp": 1735689600,
  "iat": 1563980400
}'

function pack() {
  # Remove return and space
  echo $1 | sed -e "s/[\r\n]\+//g" | sed -e "s/ //g"
}

if [ ! -f private-key.pem ]; then
  # Private and Public keys
  openssl genrsa 2048 > private-key.pem
  openssl rsa -in private-key.pem -pubout -out public-key.pem
fi

# Base64 Encoding
b64_header=$(pack "$header" | openssl enc -e -A -base64)
b64_payload=$(pack "$payload" | openssl enc -e -A -base64)
signature=$(echo -n $b64_header.$b64_payload | openssl dgst -sha256 -sign private-key.pem | openssl enc -e -A -base64)
# Export JWT 
echo $b64_header.$b64_payload.$signature > jwt.txt
# Create JWK from public key
if [ ! -d ./node_modules/pem-jwk ]; then
  # A tool to convert PEM to JWK
  npm install pem-jwk
fi
jwk=$(./node_modules/.bin/pem-jwk public-key.pem)
# Add additional fields
jwk=$(echo '{"use":"sig"}' $jwk $header | jq -cs add)
# Export JWK
echo '{"keys":['$jwk']}'| jq . > jwks.json

echo "--- JWT ---"
cat jwt.txt
echo -e "\n--- JWK ---"
jq . jwks.json

Generate private and public keys, and create JWT and JWKs

解説

秘密鍵と公開鍵の作成

if [ ! -f private-key.pem ]; then
  # Private and Public keys
  openssl genrsa 2048 > private-key.pem
  openssl rsa -in private-key.pem -pubout -out public-key.pem
fi

署名の作成

ヘッダとペイロードをBase64エンコードして、上記で作成した秘密鍵で署名を作成し、Base64エンコード。pack()は改行文字とスペースの削除用に定義した関数。

function pack() {
  # Remove return and space
  echo $1 | sed -e "s/[\r\n]\+//g" | sed -e "s/ //g"
}

b64_header=$(pack "$header" | openssl enc -e -A -base64)
b64_payload=$(pack "$payload" | openssl enc -e -A -base64)
signature=$(echo -n $b64_header.$b64_payload | openssl dgst -sha256 -sign private-key.pem | openssl enc -e -A -base64)

JWT(IDトークン)を作成

echo $b64_header.$b64_payload.$signature > jwt.txt

PEM形式の公開鍵をJWKに変換

pem-jwk - npmを使いました。

if [ ! -d ./node_modules/pem-jwk ]; then
  # A tool to convert PEM to JWK
  npm install pem-jwk
fi
jwk=$(./node_modules/.bin/pem-jwk public-key.pem)
# Add additional fields
jwk=$(echo '{"use":"sig"}' $jwk $header | jq -cs add)
# Export JWK
echo '{"keys":['$jwk']}'| jq . > jwks.json

まとめ

出力サンプル

--- JWT ---
eyJraWQiOiIxMjM0NSIsImFsZyI6IlJTMjU2In0K.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwic3ViIjoidXNlci1pZC0xMjMiLCJhdWQiOiJjbGllbnQtYXBwLWlkLTEyMyIsImV4cCI6MTczNTY4OTYwMCwiaWF0IjoxNTYzOTgwNDAwfQo=.J7GjvEODv1NeEJ3uOK99unlrtOtqMdJNydYmSStdLuiq5h+ut6E0edMjTqgJZfOMNr3vM23EJXOmk+kit/j1zGJBHgev0DoTIWrrN+fjeE7seCVZGf0eblC9VZbq9FU0t8WQz4vQeZpy1oRLIUPj6go0gw5ed8Yo+pBZi+/nPJsmy450ChfFpE1cx58VQ4zM9eEnQz4jKInevyR5cTn1iYuLhDhPQmRDdlLg3IuxgRjwxsLBjZjtiyn6mntZHOeTSAlLfmoWKNiMtN1qNoEf2e9s3pqctIwRQQKsPAfO64q//te8jGGxzTFLUV2JP23AxwzrOEcfuZyCLB5u4RKI/Q==

--- JWK ---
{
  "keys": [
    {
      "use": "sig",
      "kty": "RSA",
      "n": "4iNwSXpIvLz4DbG5HUyy5jUOnsdOD99dCA56oDWU6PSV3lTbPBWyngrdcpoC50MT_yqBMiQvaNRZRgcH82jsRrs_HPGDSMO1hEv7LUlwJy5MWBOcKeGLpAL9P9FXKnjvx2dQpWlXZC3D5KsdHc8dsMnxR8D3-T5XWDGwqnEMLWoG1uRPG7lual2PhrX3wpZMY3gmgx4WnElxv8DZs9GArvMzsojtPpgJ1cmnlzDzZbQWd5lJwW_k7S8jcEiBEwfoITzY1umQKWetMe9id1-ohH1tbe7vXpxpm59j4Fo5HZoTA3VUR6Jkbnjqf6TPhEOwJUnf-DMyewZXW2dxjvTPPw",
      "e": "AQAB",
      "kid": "12345",
      "alg": "RS256"
    }
  ]
}

各種クレームの値を変えて、IDトークンの検証をテストしたいときなどに便利かもしれないです。iss, exp, audなどの値を変えてトークンの検証が失敗するテストケースなど。

参考

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
shu-yusa
サーバーサイドエンジニア 主な関心範囲: ソフトウェアの設計、アーキテクチャ、リファクタリング、テスト、CI/CD、インフラ。 博士(理学)

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
マイクロソフト認定資格を取得する際の学習方法や経験談、おすすめ学習リソースなどを紹介しよう!
~
9
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー