自己署名証明書を表すJWKの作り方

この短い記事では、自己署名証明書を表す JWK を生成するためのコマンドラインを紹介します。

# 秘密鍵を作る

```shell
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 > private_key.pem
```

:::note warn
LibreSSL ではなく OpenSSL の `openssl`
:::

# 秘密鍵から公開鍵を抜き出す

```shell
openssl pkey -pubout -in private_key.pem > public_key.pem
```

# 当鍵ペア用の自己署名証明書を作る

```shell
openssl req -x509 -key private_key.pem -subj /CN=client.example.com -days 1000 > certificate.pem
```

# 公開鍵のフォーマットを PEM から JWK に変換する

```shell
npm install -g eckles
eckles public_key.pem > public_key.jwk
```

# 当自己署名証明書を含む JWK を生成する

```shell
CERT=$(sed /-/d certificate.pem | tr -d \\n)
jq ".+{\"x5c\":[\"$CERT\"]}" public_key.jwk > pub+cert.jwk
```

# 出力: pub+cert.jwk

```json
{
  "kty": "EC",
  "crv": "P-256",
  "x": "btjiy3sbUjxc4LKyDujKCzgh0Nv0WiVgY5k61-ZRUkI",
  "y": "Gck9a3RVmUADrHp2XPBOFxb31QIzUk6KtiWU320Qc2s",
  "x5c": [
    "MIIBjzCCATWgAwIBAgIUeaASdMyJhml/k/PQ46j9f2XJzPQwCgYIKoZIzj0EAwIwHTEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUuY29tMB4XDTIyMDYwOTA0MTE1OVoXDTI1MDMwNTA0MTE1OVowHTEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbtjiy3sbUjxc4LKyDujKCzgh0Nv0WiVgY5k61+ZRUkIZyT1rdFWZQAOsenZc8E4XFvfVAjNSToq2JZTfbRBza6NTMFEwHQYDVR0OBBYEFO4bTj08bx2Xk4SCXcndo4QaMi+yMB8GA1UdIwQYMBaAFO4bTj08bx2Xk4SCXcndo4QaMi+yMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhAKcCvn43iBxdVzE1JrEfXcEbF9TX6vxwPWyAvCzEHsQjAiBCxSFx59KDRAJys0umzxmpJkWRX1EcJkR1h9tYD8Dn1g=="
  ]
}
```

# 参考情報

- [図解 X.509 証明書](https://qiita.com/TakahikoKawasaki/items/4c35ac38c52978805c69)
- [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280.html) Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
- [RFC 7517](https://www.rfc-editor.org/rfc/rfc7517.html) JSON Web Key (JWK)
- 本記事の英語版 → [How to generate a JWK representing a self-signed certificate](https://darutk.medium.com/jwk-representing-self-signed-certificate-65276d70021b)

# 余談

インターネット上に世界規模の高信頼性デジタルアイデンティティネットワークを構築するためのプロジェクトである **GAIN** (**Global Assured Identity Network**) の [PoC](https://openid.net/gainpoc/) 用に『[GAIN PoC OpenID Connect 4 Identity Assurance Profile](https://openid.bitbucket.io/gain-poc/gain-poc-oidc4ida-profile.html)』という仮仕様が作られまして、その中で**自己署名証明書によるクライアント認証** `self_signed_tls_client_auth` ([RFC 8705](https://www.rfc-editor.org/rfc/rfc8705.html) [Section 2.2](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.2)) が要求されています。`self_signed_tls_client_auth` のためには「自己署名証明書を表す JWK ([RFC 7517 JSON Web Key](https://www.rfc-editor.org/rfc/rfc7517.html))」を用意する必要があります。

GAIN PoC に OpenID Provider の実装として Authlete を提供している関係で、当 JWK の作成方法の説明を求められる機会があり、今後も同様のことが起こると予想されましたので、取り急ぎ "[How to generate JWK representing a self-signed certificate](https://darutk.medium.com/jwk-representing-self-signed-certificate-65276d70021b)" という記事を書きました。本記事はその英語記事の日本語訳です。

2022 年 5 月におこなわれた [EIC 2022](https://www.kuppingercole.com/events/eic2022) (European Identity and Cloud Conference 2022) も GAIN の話で大盛り上がりだったようです！ Authlete 社も EIC 2022 で登壇したり (『[ICaaS (Identity Component as a Service) というアプローチ](https://www.linkedin.com/pulse/icaas-identity-component-service-%25E3%2581%25A8%25E3%2581%2584%25E3%2581%2586%25E3%2582%25A2%25E3%2583%2597%25E3%2583%25AD%25E3%2583%25BC%25E3%2583%2581-tatsuo-kudo/)』by 工藤達雄さん)、GAIN のデモをしたりしました！