环境
纯理论知识,只是笔记,非教程
二进制协议格式
每个数据包为以下格式:
类型 | 名称 |
---|---|
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 |
协议过程
协议版本交换
当 TCP 连接建立后,双方都必须发送一个标识字符。该标识字串必须是:
SSH-protoversion-softwareversion SP comments CR LF
# 我公司的服务器返回的信息
SSH-2.0-OpenSSH_5.3
名称 | 描述 |
---|---|
protoversion | 协议版本 |
softwareversion | 软件版本 |
SP | 空格 |
comments | 可选字符串 |
CR | 回车 |
LF | 换行 |
算法协商
密钥交换从每一方发送如下数据包开始:
类型 | 名称 |
---|---|
byte | SSH_MSG_KEXINIT |
byte[16] | cookie (random bytes) |
name-list | kex_algorithms |
name-list | server_host_key_algorithms |
name-list | encryption_algorithms_client_to_server |
name-list | encryption_algorithms_server_to_client |
name-list | mac_algorithms_client_to_server |
name-list | mac_algorithms_server_to_client |
name-list | compression_algorithms_client_to_server |
name-list | compression_algorithms_server_to_client |
name-list | languages_client_to_server |
name-list | languages_server_to_client |
boolean | first_kex_packet_follows |
uint32 | 0 (为将来扩展预留) |
byte SSH_MSG_KEXINIT
byte[16] cookie (random bytes)
name-list kex_algorithms
name-list server_host_key_algorithms
name-list encryption_algorithms_client_to_server
name-list encryption_algorithms_server_to_client
name-list mac_algorithms_client_to_server
name-list mac_algorithms_server_to_client
name-list compression_algorithms_client_to_server
name-list compression_algorithms_server_to_client
name-list languages_client_to_server
name-list languages_server_to_client
boolean first_kex_packet_follows
uint32 0 (为将来扩展预留)
cookie:必须是一个由发送方生成的随机值。它的作用是使任何一方都不可能对密钥和会话标识符拥有完全决定权。
kex_algorithms: 密钥交换算法。列表的话,用逗号(,)隔开
server_host_key_algorithms: 受支持的为服务器主机密钥服务的算法的名称列表,按优先级排序。通俗点说就是服务器所支持的算法列表,用逗号(,)隔开
encryption_algorithms: 可接受的对称加密算法(也称为加密器)的名称列表,按优先级排序。
mac_algorithms: 可接受的 MAC 算法的名称列表,按优先级排序。
compression_algorithms: 可接受的压缩算法的名称列表,按优先级排序。
languages: 语言标志的名称列表,按优先级排序。
first_kex_packet_follows: 表明是否有一个猜测的密钥交换数据包跟随。
Diffie-Hellman 密钥交换
首先,客户端发送:
byte SSH_MSG_KEXDH_INIT
mpint e
服务器响应如下:
byte SSH_MSG_KEXDH_REPLY
string K_S,服务器公钥和证书 (
mpint f
string s,对 H 的签名
密钥交换在每一方发送一个 SSH_MSG_NEWKEYS
消息后结束
byte SSH_MSG_NEWKEYS
参考地址: