デジタル署名文脈での公開鍵暗号方式の誤解を避けるため、署名鍵/検証鍵という表現を使うというお話

ritouです。 タイトルに全部書きましたが、Xでharuyamaさんが書かれていたものです。

よくある誤解

最近、公開鍵暗号方式がデジタル署名文脈で使われているユースケースに触れる機会が増えてきました。 自分の守備範囲でいうと

  • OpenID ConnectのIDToken
  • パスキーのAttestation/Assertion
  • 雰囲気で使われているJWT認証()

あたりでしょうか。 もちろん暗号化/復号のユースケースもあるにはあるのですが、自分の観測範囲ではデジタル署名文脈の方が圧倒的に多く使われています。

このあたりを解説しようとする記事において、誤解というか誤った認識をされがちなのが、

  • 送信者はなんらかのデータを暗号化
  • 受信者は復号して…

というものです。

デジタル署名文脈でこの表現をするのを見ると、混乱してそうだなーとなります。

プロトコルでは署名生成、検証とあるのに暗号化とか言ってしまい、さらに尾鰭が付いて送られることのない情報も暗号化によって安全に送れます!なんて主張になると完全な誤りとなってしまうわけです。パスキーでは生体情報などを暗号化して送っているわけではありません。

鍵情報の表現にも利用目的の表現がある

実際プログラムの中だと文脈そんなに気にしなくていいんじゃない?みたいなことを言われたことがありますが、そうでもないです。 JWTの鍵表現で使われるJWKでは、useというパラメータが定義されています。

use (public key use) パラメータは当該公開鍵の用途を示す. use パラメータは, その鍵が暗号化目的で提供されるのか, 署名検証目的で提供されるのかを示すために利用される.

本仕様で定義される値は以下の通りである.

  • sig (signature)
  • enc (encryption) 上記以外の値も利用可能である (MAY).

(さらに使い方を表現するkey_opsパラメータってのもいます)

こういう表現が定義されているほど、この辺りは混ぜるな危険、正しく文脈を理解しましょうということなのです。

署名鍵/検証鍵という表現

プロトコルの理解や、既存システムの理解において、文脈の理解を間違うととんでもないことになることは想像できるでしょう。 冒頭の投稿では、デジタル署名文脈において

  • 署名生成に利用する秘密鍵 = 署名鍵
  • 署名検証に利用する公開鍵 = 検証鍵

というように表現することで、誤用を避けられるのではという主張に見えました。 この表現は確かに文脈の認識がずれにくく、誤解も避けられそうな気がしますね。

自分も公開鍵暗号方式のデジタル署名を利用する仕組みなどを説明したり誤解/誤用を見つけた際はこの表現を利用していこうかと思います。 ID連携の仕様ではprivate_key/public_keyとかが使われているのでそのまま使ってしまいがちですが、共通理解を得るためには柔軟性も必要ですね。

ではまた。

※7/14 追記

この投稿に関して「公開鍵/秘密鍵 という表現をやめることによるデメリット」を指摘する反応が多いように感じました。

  • 秘密鍵を公開しそう
  • 公開鍵を公開していいということがわからなそう

代わりにこういう表現を使おうという主張にしたので、それはごもっともです。 自分の感じている課題はその鍵ペアがあるとなった上で「どのような使われ方をするか」のところが安易に「暗号化/復号」に繋げられてしまうことに課題感を持っているというところなので、秘密鍵/公開鍵それぞれの公開してもいいかみたいなところに影響を与えることは本意ではありません。

というところで、現実的にはデジタル署名文脈での説明においては「秘密鍵/公開鍵は署名鍵/検証鍵として振る舞うのだよ」というような補足をしながら共通認識を持てるようにする、というあたりを意識しています。

署名の文脈で...と言っているので暗号化/復号の話の時に混乱する、みたいな反応も見られましたが、そっちの文脈の定義を崩したいわけではないので話を混ぜないようにしようというのも主張に含まれます。