秘密情報(パスワードの類)を安全に共有するための Diffie-Hellman(DH)鍵交換を実際に試してみよう。盗聴されても大丈夫だが,中間者攻撃(MITM)には注意しなければならない。
Diffie-Hellman Key Exchange というページではブラウザ(JavaScript)で実行できるようになっているが,手動で行う方法も書いてある。以下では $
とその左側はプロンプトである(打ち込まない)。まず
$ openssl genpkey -genparam -algorithm DH -out param.pem
でパラメータ param.pem を生成し,共有する(盗聴されてもかまわない)。次に,このパラメータを使って,Alice と Bob は秘密鍵・公開鍵を作る:
A$ openssl genpkey -paramfile param.pem -out priv1.pem A$ openssl pkey -in priv1.pem -pubout -out pub1.pem B$ openssl genpkey -paramfile param.pem -out priv2.pem B$ openssl pkey -in priv2.pem -pubout -out pub2.pem
互いの公開鍵を交換し(盗聴されてもかまわない),自分の秘密鍵と相手の公開鍵から,秘密情報を作る:
A$ openssl pkeyutl -derive -inkey priv1.pem -peerkey pub2.pem -out shared1.bin B$ openssl pkeyutl -derive -inkey priv2.pem -peerkey pub1.pem -out shared2.bin
秘密情報は等しい(shared1.bin == shared2.bin)。バイナリなので,パスワードにして使いたいときは,Base64 に変換すればよい:
A$ base64 shared1.bin B$ base64 shared2.bin
楕円曲線(elliptic curve)を使った ECDH 鍵交換もしてみよう。Creating elliptic curve ECDH key with openssl や Command-line Elliptic Curve operations を参照した。
まず,どんな楕円曲線が使えるか調べる。CentOS 7 上の OpenSSL では
$ openssl version OpenSSL 1.0.2k-fips 26 Jan 2017 $ openssl ecparam -list_curves secp256k1 : SECG curve over a 256 bit prime field secp384r1 : NIST/SECG curve over a 384 bit prime field secp521r1 : NIST/SECG curve over a 521 bit prime field prime256v1: X9.62/SECG curve over a 256 bit prime field
macOS (Monterey) 上の OpenSSL の中身は LibreSSL である:
% openssl version LibreSSL 2.8.3 % openssl ecparam -list_curves (たくさん)
一番長い secp521r1 を使うことにする。まずパラメータを生成する:
$ openssl ecparam -name secp521r1 -out param.pem
このあとは通常のDH鍵交換と同じである。
もっとも,生成されるパラメータは一定のようなので,パラメータの生成をさぼって,次のようにしてもよさそうだ:
A$ openssl ecparam -name secp521r1 -genkey -noout -out key1.pem A$ openssl pkey -in key1.pem -pubout -out pub1.pem B$ openssl ecparam -name secp521r1 -genkey -noout -out key2.pem B$ openssl pkey -in key2.pem -pubout -out pub2.pem A$ openssl pkeyutl -derive -inkey key1.pem -peerkey pub2.pem -out shared1.bin B$ openssl pkeyutl -derive -inkey key2.pem -peerkey pub1.pem -out shared2.bin