以下の内容は、SSH Version 2 を元にして書いています。
下記のサイトを参考に学習をしていました。
sshの進化
多くのサイトで SSH の説明として書かれている内容は間違いが多く含まれています。
上記のサイトに書かかれている内容も、いろいろと間違いが見受けられるので、鵜呑みにするのは危険です。
(1) セッション鍵交換では、DH鍵交換方式を利用するため、セッション鍵生成に必要な値の送受信は暗号化することなく、行うことができる。(盗聴しても、鍵生成に必要な、判明している変数が足りないため。Wiki DH鍵共有)
セッション鍵交換と呼ぶのはちょっと微妙ですね。鍵交換(Key Exchange:SSHではKEXとも呼ぶ)の目的は、shared secretとexchange hashと呼ばれる二つの値の共有です。また、最初のKEXで共有されたexchange hashはsession-idとも呼ばれて特別な意味を持ちます。
これらのshared secret, exchange hash, session-id を元にして、
- 通信暗号化用の共通鍵
- 通信暗号化用のIV
- メッセージ認証用の鍵
を生成します。
ここでは、その後のホスト、ユーザ認証や、セッション確立後の通信に使用する暗号化復号化に利用する、いわゆる共通鍵を作成しているのですか?
通信自体はKEXの後のホスト認証(実際にはKEXの手順の一部)が終わった時点で暗号化が開始されます。
そしてKEXでは通信暗号化用の共通鍵だけではなく、IV、メッセージ認証用の鍵も同時に生成します。
ホスト認証は一般にそう呼ばれる事が多いのですが、前述したように実際にはKEXの手順の一部です。
WikipediaのDH鍵共有 にあるように、DH鍵共有は中間者攻撃に対して脆弱です。これへの対策として、サーバはKEXの最終段階でexchange hashに対してホスト鍵で署名を行い、ホスト鍵と一緒に署名をクライアントに送信します。
そしてクライアントは、
- ホスト公開鍵が接続したいホストの正しい鍵か
- exchange hashの署名が正しいか
を確認する事によって、KEXの手順が改ざんされていない事、および正しいホストと通信している事を確認します。
なので、ホスト認証で共有した値を使うというよりは、共有した値が正しいかをホスト認証で確認するというのが正しいです。
KEXで共有した値が(通信路の暗号化とは別に)ユーザ認証で使われるかは、認証方式によって変わります。
(2) ホスト認証では、サーバーがホスト公開鍵をクライアントに送信し、クライアントの~/.ssh/known_hostsと照合するとありますが、ここでいうホスト公開鍵とは、ssh接続を行う時に用いる、ssh-keygenで生成した公開鍵とは全くの別物であると考えていいですか?
「ssh-keygenで生成した公開鍵」がユーザ認証で使う公開鍵の意味でしたら、ホスト公開鍵はこれとは別物です。
ただし、ホスト公開鍵も通常はサーバインストール時にssh-keygenコマンドによって生成されます。
(3)ユーザ認証では、パスワード認証、公開鍵認証(ssh-keygenで予め作成した鍵を使用)などといった認証方法が用いられると考えていいのですか?
はい。SSHの認証方式には以下のような物が有ります。
- パスワード認証
- 公開鍵認証
- ホストベース認証 (ホスト単位で認証するので、厳密にはユーザ認証では無いですが)
- keyboard-interactive認証
- GSS-API 認証
(4)共通鍵暗号/公開鍵暗号に記載されているような、「共通鍵を、公開鍵暗号方式で送信するといった作業」は(1)~(3)の中には無いように見えますが、sshでは「共通鍵を、公開鍵暗号方式で送信するといった作業」は無いと考えてよいですか?
おおむねその通りと考えていいと思います。
ssh通信で使うホスト鍵や認証用鍵にはRSAの他にDSAやECDSA, ED25519鍵などが使われます。
この内 DSA, ECDSA, ED25519鍵は署名用の方式であり、暗号化が行えない事を考えれば、公開鍵による暗号化が行われない事が判ると思います。
厳密な話を書くと、KEXではDH鍵共有を使う他にRSA暗号を使う方式も有ります。この時はshared secretがRSA鍵で暗号化されて送られるので、「共通鍵を、公開鍵暗号方式で送信するといった作業」というのに近い事は行われます。
ただしOpenSSHではRSAでの鍵共有に対応していない為、実際に使われる事は少ないでしょう。
クライアントではPuTTYがRSAでの鍵共有に対応しています。
コメントに対して、ここだけは訂正した方がいいと思う点を一点だけ追記します。
SSHでは鍵交換で共有される shared secret および exchange hash (セッションIDも含む) はとても重要な情報であり、これらがネットワーク上を流れる事は有りません。(暗号化された状態も含めて)
③ホスト認証
(1)サーバーはセッションIDをホスト秘密鍵で暗号化し、セッションIDとセッションIDの暗号化したものを、クライアントに送信する。
なので、ここでもサーバはセッションID(正確にはexchange hash)に対して署名(暗号化ではありません)を行い、作成された署名データのみを送ります。(正確にはホスト公開鍵、および鍵交換で送るデータの二つも一緒に送る)
(2)クライアントは受け取ったセッションIDを、暗号化されたセッションIDをサーバーの公開鍵で復号化したものと比較し、一致したら、ホストを正式なものと認証する。
クライアント側は
- 鍵交換の手順として、shared secret および exchange hash を計算する
- 送られてきた署名データが、計算して得られた exchange hash に対する正しい署名データである事を一緒に送られてきたホスト公開鍵で検証する
- 送られてきたホスト公開鍵が .ssh/known_hosts に登録されているかを確認し、登録されていなかったり登録されている物と異なっていた場合はユーザに確認を求める
という事を行います。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/11 22:08
2019/06/13 20:00 編集
2019/06/17 09:40