web-dev-qa-db-ja.com

SSH公開鍵認証はどのように機能しますか?

私の基本的な理解はこれです:

  • (接続されている)サーバーのsshdは、公開鍵を使用してメッセージを暗号化します
  • クライアントのsshまたは_ssh-agent_はそれを復号化して何かを返します(メッセージのチェックサム?署名?)
  • サーバーのsshdは、これがユーザーを認証するメッセージと一致していることを確認します

しかし、詳細は何ですか? 「何らかのメッセージ」とは何ですか、ssh(-agent)は何を送り返しますか?同じ元のメッセージを使用してこれを何度も繰り返すと、常に同じ通信が得られますか?

_ssh-agent_が使用されている場合、この認証プロセスをbashツールを介して再生できますか?例えば。 _ssh-agent_が提供する公開鍵は_ssh-add -L_を介して取得できますが、残りのプロセスについてはどうですか?または、手動で_$SSH_AUTH_SOCK_ UNIXソケットに接続し、低レベルの通信を行う必要がありますか?


関連: Thomas 'Server-Bob dialogue here ただし、クライアントがサーバーデータの_authenticated_keys_のすべての公開キーに対してチェックされるランダムデータに署名することを示唆しています。 この図 一方、メッセージは以前に決定されたユーザーの公開鍵(ssh暗号化用ではない)で暗号化され、クライアントはチェックサムを出力します。これは、ランダムセッションIDにも依存します。どちらが正しいか?それともどちらも、実際にはもっと複雑な話の一部しか伝えていませんか?

46
Tobias Kienzler

認証の詳細は、プロトコルのバージョンとキーのタイプによって異なります。いずれの場合も、リプレイ攻撃を回避するためにある程度のランダム性があり、常に課題があります。ユーザー鍵のタイプがDSAの場合、DSAは署名のみのアルゴリズムであるため、真のデジタル署名が必ず含まれます。リンク先の記事は、ユーザーキーが非対称暗号化を実行できることを前提としているものを示しています。これはSSHv1が行ったものだと思います(SSHv1では、すべてのキーがRSAであり、RSAは非対称暗号化を行うことができます)。現在の(SSHv2)プロトコルの場合、公開鍵ベースのクライアント認証は RFC 4252 のセクション7で指定されています。

コアの概念は同じです。クライアントは、秘密鍵の知識を必要とする操作を実行することによって秘密鍵の制御を証明しますが、「逆」操作は、.ssh/authorized_keysにある公開鍵を使用して実行できますサーバ。

15
Thomas Pornin

簡単に言えば:

  • SSHv1:サーバーはメッセージをauthorized_keysに保存されている公開鍵で暗号化し、クライアントはそれを復号してチェックサム(セッションIDによって変更)を返す必要があります
  • SSHv2:クライアントは(セッションIDに応じて)メッセージに署名し、使用された公開鍵を使用してメッセージなしで署名を送信します。次に、サーバーはメッセージを再作成して署名を検証します(公開鍵が実際にauthorized_keysにある場合)

ドキュメント PROTOCOL.agent はこれを要約しています:

暗号の使用法が異なるため、プロトコル1とプロトコル2のキーは分離されています。プロトコル1のプライベートRSAキーは、対応する公開キーで暗号化されたチャレンジの復号化に使用されますが、プロトコル2のRSAプライベートキーは、対応する公開鍵による検証。署名と暗号化に同じキーを使用することは、不健全な慣行と見なされています。

RFC 4252 のSSHv2関連セクションは次のとおりです。

実際の認証を実行するために、クライアントは次に
秘密鍵を使用して生成された署名。クライアントは、
最初にキーを確認せずに直接署名
許容できます。署名は次のパケットを使用して送信されます。

  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication
  string    signature

'signature'の値は、次のデータの対応する秘密鍵による次の順序の署名です。

  string    session identifier
  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication

サーバーはこのメッセージを受信すると、
提供されたキーは認証に受け入れ可能であり、受け入れ可能な場合は、
署名が正しいかどうかを確認します。

29
Tobias Kienzler