最終更新: haruyama_seigo 2011年07月15日(金) 17:20:20履歴
https://github.com/haruyama/ssh_client_sample/blob...
private def exchangeKeys(transportManager: TransportManager, clientVersion: String, serverVersion: String, clientKexinit: Kexinit, serverKexinit: Kexinit) = { //ch.ethz.ssh2.crypto.dh.DhExchange を利用して //diffie-hellman-group1-sha1 鍵交換法を行なう準備をする val dhx = new DhExchange dhx.init(1, new SecureRandom); // SSH_MSG_KEXDH_INIT メッセージを送信する val kexdhInit = DhExchangeMessageBuilder.buildKexdhInit(dhx.getE()) transportManager.sendMessage(kexdhInit) // SSH_MSG_KEYDH_REPLY メッセージを受信する val kexDhReply = transportManager.recvMessage().asInstanceOf[KexdhReply] // SSH_MSG_KEYDH_REPLY にホスト公開鍵をローカルなデータベースなどで検証し // 接続先ホストを認証しなければならない.ここでは省略する // 交換ハッシュ H を計算する dhx.setF(kexDhReply.f.value) val h = dhx.calculateH(clientVersion.getBytes, serverVersion.getBytes, clientKexinit.toBytes, serverKexinit.toBytes, kexDhReply.hostKey.value) // SSH_MSG_KEYDH_REPLY 中に H の署名がついている.これをホスト公開鍵で検証する val rs = RSASHA1Verify.decodeSSHRSASignature(kexDhReply.sigOfH.value) val rpk = RSASHA1Verify.decodeSSHRSAPublicKey(kexDhReply.hostKey.value) if (!RSASHA1Verify.verifySignature(h, rs, rpk)) new RuntimeException("RSA Key is not verified") // 交換ハッシュ H と 共有の秘密 K を返す (h, dhx.getK) }
Diffie-Hellman 鍵交換を行ないます. Diffie-Hellman の実装は Ganymed SSH-2 for Java を利用しています.
この鍵交換では, 交換ハッシュ H と共有の秘密 K が交換されます.
共有の秘密 K は, Diffie-Hellman 鍵交換により計算されます.
交換ハッシュ H は, バージョン文字列, SSH_MSG_KEXINIT メッセージ, サーバのホスト公開鍵, Diffie-Hellman 鍵交換でやりとりされる値 を連結したもののハッシュです.
以上の2つから, 暗号化のための鍵とIV, MACのための鍵を計算します.
鍵交換のために, e と呼ばれる値を生成しこれを SSH_MSG_KEXDH_INIT メッセージで送信します.
byte SSH_MSG_KEXDH_INIT mpint e
応答として SSH_MSG_KEYDH_REPLY がサーバから送られてきます.
byte SSH_MSG_KEXDH_REPLY string server public host key and certificates (K_S) mpint f string signature of H
- server public host key and certificates (K_S)
- サーバホスト公開鍵
- f
- Diffie-Hellman 鍵交換で利用する値
- signature of H
- サーバの秘密鍵による H の署名
クライアントは, サーバホスト公開鍵をローカルなデータベースなどによって検証します. OpenSSH では ~/.ssh/known_hosts にサーバ名と公開鍵のセットが登録されているか検索します. 登録されていなかったりサーバ名に対する公開鍵が異なる場合は警告を出します. この警告を無視すると, クライアントが本来接続したいサーバではない接続する可能性があります.
サンプルプログラムでは, この検証は省略しています.
共有の秘密 K は Diffie-Hellman 鍵交換の結果計算されます.
交換ハッシュ H は, バージョン文字列, SSH_MSG_KEXINIT メッセージ, サーバのホスト公開鍵, Diffie-Hellman 鍵交換でやりとりされる値 をハッシュ(この場合はsha1)化して計算されます.
交換ハッシュ H に対する署名が SSH_MSG_KEYDH_REPLY に含まれています. これを検証し, サーバがホスト公開鍵に対応する秘密鍵を持っていることを検証します.
- カテゴリ:
- インターネット
- インターネットセキュリティ
最新コメント