SSHクライアントとサーバの間のやりとりは, SSHのメッセージを利用します. ただし, SSHのメッセージをそのまま(TCPなどの)基底のトランスポート上で通信するわけではありません. パディングやMACの付与, 暗号化, 圧縮をメッセージに対して行なったパケットを実際にはやりとりします.

SSHのパケットは, TCPのパケットとは異なるものです.

以下での, メッセージ, パケットという表記は, それぞれSSHのものを意味します.

メッセージ

メッセージの構成


メッセージは, メッセージID(byte) とメッセージ固有の情報で構成されます.

メッセージID


各メッセージには, 番号が割り当てられています.
RFC4250 4.1.2 で定義されているメッセージID(一部)
Message ID                            Value    Reference
-----------                           -----    ---------
SSH_MSG_DISCONNECT                       1     [SSH-TRANS]
SSH_MSG_IGNORE                           2     [SSH-TRANS]
SSH_MSG_UNIMPLEMENTED                    3     [SSH-TRANS]
SSH_MSG_DEBUG                            4     [SSH-TRANS]
SSH_MSG_SERVICE_REQUEST                  5     [SSH-TRANS]
....

メッセージの例

例1: SSH_MSG_NEWKEYS

通信で利用する鍵を新しいものに変更する際に送るメッセージです.
鍵そのものは事前に鍵交換プロトコルによって安全に交換されているので,
メッセージ固有の情報はなく, 1 byte のメッセージです.

byte      SSH_MSG_NEWKEYS (21)


例2: SSH_MSG_CHANNEL_REQUEST

SSH_MSG_CHANNEL_REQUEST はシェルの起動とコマンドの実行, サブシステムの起動などを要求するメッセージです. 以下では, シェルの起動とコマンドの実行 の場合を挙げます.

シェルの起動

byte      SSH_MSG_CHANNEL_REQUEST (98)
uint32    recipient channel
string    "shell"
boolean   want reply

コマンドの実行

byte      SSH_MSG_CHANNEL_REQUEST (98)
uint32    recipient channel
string    "exec"
boolean   want reply
string    command
このように, 同じメッセージIDでもメッセージの構成が異なる場合があります.

パケット


前述のように, SSHの通信では, パディングやMACの付与, 暗号化, 圧縮をメッセージに対して行なったパケットを実際にはやりとりします.

パケットの構造

アルゴリズムがまだ決まっていない場合

暗号化やMAC, 圧縮についてまだ決まっていない場合は,
以下の内容がそのまま相手に送信されます.

uint32    packet_length
byte      padding_length
byte[n1]  payload; n1 = packet_length - padding_length - 1
byte[n2]  random padding; n2 = padding_length


byte[n1] は 長さ n1 のbyteの配列です.
  • packet_length は, byte単位でのパケットの長さです. ただし,packet_length 自体の長さ (4byte) は含みません.
  • padding_length は, random padding の長さです. すくなくとも 4 byte のパディングが必要です. このパケット全体の長さが, byte単位で8 の倍数になるような値を設定します. (暗号アルゴリズムが決まっている場合は, 暗号のブロックサイズか8のどちらか大きいほうの倍数になるようにします)
  • payload は, SSHのメッセージです.
  • random padding は, padding_length の長さのランダムなパディングです.
ランダムでなければなりません.

SSH_MSG_NEWKEYS メッセージの場合には, 以下のようになります.
  1. SSH_MSG_NEWKEYS は 1 byte (21, 0x15) のメッセージです.
  2. パケット長を8の倍数にするには, padding_length(random padding) の長さを 10(0x0a) にする必要があります (padding_length が 2 でも8の倍数になりますが, 4 以上にしなければいけないという制限があります).
  3. このときパケット全体の長さは 16 byte で packet_length は 12(0x0c) になります(自身の長さを含まないので).


アルゴリズムが決まっている場合

暗号化やMAC, 圧縮のアルゴリズムが決まっている場合, 次の内容が相手に送られます.

uint32    packet_length
byte      padding_length
byte[n1]  payload; n1 = packet_length - padding_length - 1
byte[n2]  random padding; n2 = padding_length
byte[m]   mac (Message Authentication Code - MAC); m = mac_length
  • packet_length, padding_length, payload, random padding は前述とほど同様です. ただし以下が異なります.
    • 圧縮アルゴリズムが "none" でなければ, payload は圧縮されます.
    • 暗号化アルゴリズムが "none" でなければ(通常は "none" ではありません), packet_length, padding_length, payload, random padding の内容が暗号化されます.
  • MACアルゴリズムが, "none" でなければ(通常は "none" ではありません), mac が付きます.
    • MACは, 暗号化前のパケットに対して計算します.
    • mac_length(MACの長さ)は, アルゴリズムに依存します. hmac-md5 なら 16byte, hmac-sha1 なら 20byte です.
  • 暗号などの鍵やIV, カウンタは, 事前に取り決められています. これらは送信されることはありません.

以下の条件の場合に SSH_MSG_NEWKEYS メッセージを含むパケットがどのようになるかを図で示します.
  • 暗号化アルゴリズムのブロックサイズは8か16 (aes128-ctrなど)
  • MACアルゴリズムのサイズは20 (hmac-sha1など)
  • 圧縮アルゴリズムは “none”

メンバーのみ編集できます