Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ecdsa(楕円曲線)の公開鍵でも暗号・復号できるようにしたい #69

Open
yoshi389111 opened this issue Mar 6, 2023 · 1 comment

Comments

@yoshi389111
Copy link
Collaborator

yoshi389111 commented Mar 6, 2023

ecdsaの公開鍵でも、ecdh鍵交換をして暗号・復号はできるみたいですね。
ちょっと面倒な感じなので本当にやるかどうかはおいといて、とりあえず方法をメモしておきます。

手順1)Alice が GitHub に公開鍵を登録

Alice が SSH 用の秘密鍵と公開鍵を生成。例として、521bit の楕円曲線を使う。(※512bit じゃない)

ssh-keygen -t ecdsa -b 521 -f ./id_ecdsa -C comment
  • id_ecdsa - Alice の秘密鍵
  • id_ecdsa.pub - Alice の公開鍵

公開鍵を GitHub で公開しておく

手順2)Bob がデータを暗号化して送付

Bob は、Alice の公開鍵を curl 等でゲットする。

curl https://github.com/【aliceのアカウント】.keys > id_ecdsa_alice.pub

OpenSSH 形式の公開鍵( ecdsa-sha2-nistp521 で始まる1行)を PEM 形式( -----BEGIN PUBLIC KEY----- みたいなやつ )に変換

ssh-keygen -f id_ecdsa_alice.pub -e -m PKCS8 > pub_alice.pem

Bob は使い捨ての秘密鍵・公開鍵のペアを生成する。Alice の公開鍵に合わせて 521bit の secp521r1 で生成。

openssl ecparam -name secp521r1 -genkey -noout -out key_bob.pem
openssl pkey -in key_bob.pem -pubout -out pub_bob.pem
  • key_bob.pem - 使い捨ての Bob の秘密鍵
  • pub_bob.pem - 使い捨ての Bob の公開鍵

生成した使い捨ての秘密鍵と、Alice の公開鍵をもとに、交換する鍵を生成する。

openssl pkeyutl -derive -inkey key_bob.pem -peerkey pub_alice.pem -out shared.bin

生成された交換鍵 shared.bin はバイナリなので、これをもとに共通鍵暗号の鍵をいい感じに生成する。

(ハッシュ化するとか、base64にしてパスワードにするとか、そのまま使うとか?)

Bob が Alice に送りたいデータを、(上記の鍵を使って)共通鍵暗号アルゴリズムで暗号化する。

Bob は、暗号化したファイルと、使い捨ての公開鍵 pub_bob.pem をアーカイブして、Alice に送付する。

手順3)Alice は送られてきた暗号化データを復号する

Alice は、自分の秘密鍵 id_ecdsa (OpenSSH の新形式の場合には旧型式に変換要)と、送られてきた Bob の使い捨ての公開鍵 pub_bob.pem で、交換鍵 shared.bin を生成する。

秘密鍵の変換が必要なら( -----BEGIN OPENSSH PRIVATE KEY----- みたいなやつなら)

cp id_ecdsa id_ecdsa.copy
ssh-keygen -p -N "" -m pem -f id_ecdsa.copy # 上書きされる
openssl pkeyutl -derive -inkey id_ecdsa.copy -peerkey pub_bob.pem -out shared.bin
rm id_ecdsa.copy

変換不要なら( -----BEGIN EC PRIVATE KEY----- みたいなやつなら)

openssl pkeyutl -derive -inkey id_ecdsa -peerkey pub_bob.pem -out shared.bin

shared.bin (Bob が生成したものと同じバイナリになるはず)をもとに、 Bob と同じ方法で共通鍵を生成して、送られてきた暗号ファイルを復号する。

参考

奥村先生のサイトの「ECDH鍵交換」を参考にしました。

https://okumuralab.org/~okumura/misc/211210.html

@KEINOS
Copy link
Member

KEINOS commented Mar 6, 2023

おお!

実は、お互いの公開鍵から共通秘密鍵(Common Secret)を作れないか、密かに悩んでいました。ナイスインフォです。

というのも、最近 TOTP(ワンタイムパスワード) に凝っていて、「もぅ、なんでも TOTP でいいじゃない」とすら感じています。そんな中、OTP の秘密鍵は n バイトのランダム値で良いことに気づきました。

そして「お互いの公開鍵から生成された共通秘密鍵を OTP の秘密鍵にしちゃえばサイトやアプリのログインにも使えて面白いじゃない」と思ったのです。

となると、どのように共通鍵を作るかが問題になります。やはり有用なのが奥村先生のリンクにもあります「DH 鍵交換」だと思います。

hashアルゴリズムとハッシュ値の長さ一覧(+ハッシュ関数の基本と応用) @ Qiita より

上記 DH 鍵交換の図において、最初の共通パラメーター(図で言う「共通色」)をどうするかが悩みだったのですが、代数曲線をパラメーターのジェネレーターとして使うことまでは理解したものの難しく。また、そのパラメーターの定数をシェアする必要もあり、手順が煩雑だなぁと思ってました。

相手が ecdsa で作成した公開鍵であれば、そこから楕円曲線でパラメーターが作れるということに目からウロコです。

まだ咀嚼できていませんが、これは、本当に良い情報を得ました。何かが自分の中で一歩進みました。ありがとうございます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants