OpenSSH 5.8の内部動作を調べていて、分からない点があります。
「実用SSH 第2版」のSSH-TRANSプロトコルの章に、鍵交換を行う際、中間介入攻撃の防止のためにセッションごとに一意となるような交換ハッシュHを求めるという記載があります。
どのような方法で、セッションごとに一意となるような交換ハッシュを算出しているのか、お教え頂きたいです。
宜しくお願いします。
SSH, the secure shell: the ... - Google ブックス
おそらく、原著だと上記のページ辺りから始まる話だと思いますが、セッション鍵は基本的に乱数から作られます。上記の原著の記述だと、7つあるステップの5番目「5. The client sends the server a secret (session) key.」に対する解説(55 ページ)で、
Now the client randomly generates a new key for a bulk cipher [3.2.2] that both client and server support; this is called the session key.
と書かれています。ざっくり意訳すると、「クライントとサーバの両方でサポートする暗号化方式のうち、最も安全な暗号化方式に対する新しい鍵を、クライアントがランダムに生成します。これがセッションキーになります」といった話になります。
余談ですが、SSL/TLS も同様の戦略を取ります。通信の暗号化の場合、通信内容そのものの暗号化に使う鍵を、都度、乱数から生成します。通信の暗号化は、End to End で通信が成立してしまえば、後から暗号文を復号化する必要は無いので、セッション毎に使い捨ての鍵が使われます。
問題は、その使い捨ての鍵を、どうやって安全にクライアントとサーバの間でやり取りするかで、SSH では Diffie-Hellman を使うようです。
追記:
私も勘違いしてました。今、焦点になっているのは、「交換ハッシュ」の方ですよね。
下記のページが分かりやすいと思います。
ssh/SSHプロトコル概要/鍵交換 - 春山征吾のWiki - livedoor Wiki(ウィキ)
交換ハッシュ H は, バージョン文字列, SSH_MSG_KEXINIT メッセージ, サーバのホスト公開鍵, Diffie-Hellman 鍵交換でやりとりされる値 を連結したもののハッシュです.
で、この鍵交換の SSH_MSG_KEYDH_REPLY の段階で、H に対してサーバの秘密鍵で署名した値が返ってきているので、この署名を検証することで、中間者が設定したものではないことが分かります。
じゃぁ、署名を検証する時の公開鍵は本物か? という点が残るのですが、SSH では、クライアント側が以前に取得した公開鍵を保存していて、それと付きあわせて、確認していることになります。初めて繋いだ時に、「このホスト鍵、信用していい? 信用していいんなら保存しておくけど」と言われるのはこのためです。
余談:
SSL/TLS だと、公開鍵に署名があって、その署名が、信頼済みの認証局の公開鍵で検証できるか、という話になります。
閑話休題。
で合ってるかな? これ以上は私が理解できる範疇を超えるので、例えば、Diffie-Hellman 鍵交換の計算がどうのこうの、と言われると、お手上げです(^^;。
ssh-keygen でパスフレーズをベースに生成されるハッシュ値です。
回答ありがとうございます。
交換ハッシュは接続ごとに一意となるものと認識しているのですが、この認識が誤っているのでしょうか。
パスフレーズをベースにしたハッシュ値は接続ごとに一意とならないイメージがあるので、中間者介入攻撃の防止との関連が見えていない状態です。
ssh-keygen でパスフレーズをベースに生成されるハッシュ値?だとおもいます
回答ありがとうございます。以下の点について、もしご存知であればお教えください。宜しくお願いします。
> 交換ハッシュは接続ごとに一意となるものと認識しているのですが、この認識が誤っているのでしょうか。
>
> パスフレーズをベースにしたハッシュ値は接続ごとに一意とならないイメージがあるので、中間者介入攻撃の防止との関連が見えていない状態です。
SSH, the secure shell: the ... - Google ブックス
おそらく、原著だと上記のページ辺りから始まる話だと思いますが、セッション鍵は基本的に乱数から作られます。上記の原著の記述だと、7つあるステップの5番目「5. The client sends the server a secret (session) key.」に対する解説(55 ページ)で、
Now the client randomly generates a new key for a bulk cipher [3.2.2] that both client and server support; this is called the session key.
と書かれています。ざっくり意訳すると、「クライントとサーバの両方でサポートする暗号化方式のうち、最も安全な暗号化方式に対する新しい鍵を、クライアントがランダムに生成します。これがセッションキーになります」といった話になります。
余談ですが、SSL/TLS も同様の戦略を取ります。通信の暗号化の場合、通信内容そのものの暗号化に使う鍵を、都度、乱数から生成します。通信の暗号化は、End to End で通信が成立してしまえば、後から暗号文を復号化する必要は無いので、セッション毎に使い捨ての鍵が使われます。
問題は、その使い捨ての鍵を、どうやって安全にクライアントとサーバの間でやり取りするかで、SSH では Diffie-Hellman を使うようです。
追記:
私も勘違いしてました。今、焦点になっているのは、「交換ハッシュ」の方ですよね。
下記のページが分かりやすいと思います。
ssh/SSHプロトコル概要/鍵交換 - 春山征吾のWiki - livedoor Wiki(ウィキ)
交換ハッシュ H は, バージョン文字列, SSH_MSG_KEXINIT メッセージ, サーバのホスト公開鍵, Diffie-Hellman 鍵交換でやりとりされる値 を連結したもののハッシュです.
で、この鍵交換の SSH_MSG_KEYDH_REPLY の段階で、H に対してサーバの秘密鍵で署名した値が返ってきているので、この署名を検証することで、中間者が設定したものではないことが分かります。
じゃぁ、署名を検証する時の公開鍵は本物か? という点が残るのですが、SSH では、クライアント側が以前に取得した公開鍵を保存していて、それと付きあわせて、確認していることになります。初めて繋いだ時に、「このホスト鍵、信用していい? 信用していいんなら保存しておくけど」と言われるのはこのためです。
余談:
SSL/TLS だと、公開鍵に署名があって、その署名が、信頼済みの認証局の公開鍵で検証できるか、という話になります。
閑話休題。
で合ってるかな? これ以上は私が理解できる範疇を超えるので、例えば、Diffie-Hellman 鍵交換の計算がどうのこうの、と言われると、お手上げです(^^;。
詳細に回答頂きありがとうございます。
私の質問が悪かったのですが、中間者が介入している、していない、という判定をどのように行っているのかを知りたかったです。
交換ハッシュは、クライアント↔中間者、中間者↔サーバの2つの接続において、中間者が勝手に設定できないようなデータを使用して決定される、という認識があります。
この「中間者が勝手に設定できないデータ」とは何なのかをお教え頂ければと思います。
追記への返信:
追加の情報ありがとうございます。大変参考になりました。
改めて最初の質問を見直しますと、『サーバの秘密鍵で署名する対象が「クライアントが生成した乱数」ではダメで「交換ハッシュ」なのはなぜか?』という言い方の方が伝わりやすかったかもしれません。
JULYさんの回答を踏まえまして、交換ハッシュを作成する情報の中に「Diffie-Hellman 鍵交換でやりとりされる値」が含まれているため、中間者を介した接続かどうかを判別することが可能、という認識になりました。
※ 本当にこれで合っているのかは更に調査が必要そうですが…。
どうもありがとうございました。
詳細に回答頂きありがとうございます。
私の質問が悪かったのですが、中間者が介入している、していない、という判定をどのように行っているのかを知りたかったです。
交換ハッシュは、クライアント↔中間者、中間者↔サーバの2つの接続において、中間者が勝手に設定できないようなデータを使用して決定される、という認識があります。
この「中間者が勝手に設定できないデータ」とは何なのかをお教え頂ければと思います。
追記への返信:
追加の情報ありがとうございます。大変参考になりました。
改めて最初の質問を見直しますと、『サーバの秘密鍵で署名する対象が「クライアントが生成した乱数」ではダメで「交換ハッシュ」なのはなぜか?』という言い方の方が伝わりやすかったかもしれません。
JULYさんの回答を踏まえまして、交換ハッシュを作成する情報の中に「Diffie-Hellman 鍵交換でやりとりされる値」が含まれているため、中間者を介した接続かどうかを判別することが可能、という認識になりました。
※ 本当にこれで合っているのかは更に調査が必要そうですが…。
どうもありがとうございました。