ecdsa(楕円曲線)の公開鍵でも暗号・復号できるようにしたい
Opened this issue · 1 comments
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鍵交換」を参考にしました。
おお!
実は、お互いの公開鍵から共通秘密鍵(Common Secret)を作れないか、密かに悩んでいました。ナイスインフォです。
というのも、最近 TOTP(ワンタイムパスワード) に凝っていて、「もぅ、なんでも TOTP でいいじゃない」とすら感じています。そんな中、OTP の秘密鍵は n バイトのランダム値で良いことに気づきました。
そして「お互いの公開鍵から生成された共通秘密鍵を OTP の秘密鍵にしちゃえばサイトやアプリのログインにも使えて面白いじゃない」と思ったのです。
となると、どのように共通鍵を作るかが問題になります。やはり有用なのが奥村先生のリンクにもあります「DH 鍵交換」だと思います。
hashアルゴリズムとハッシュ値の長さ一覧(+ハッシュ関数の基本と応用) @ Qiita より |
上記 DH 鍵交換の図において、最初の共通パラメーター(図で言う「共通色」)をどうするかが悩みだったのですが、代数曲線をパラメーターのジェネレーターとして使うことまでは理解したものの難しく。また、そのパラメーターの定数をシェアする必要もあり、手順が煩雑だなぁと思ってました。
相手が ecdsa で作成した公開鍵であれば、そこから楕円曲線でパラメーターが作れるということに目からウロコです。
まだ咀嚼できていませんが、これは、本当に良い情報を得ました。何かが自分の中で一歩進みました。ありがとうございます。