【发布时间】:2016-04-17 01:00:35
【问题描述】:
出于学习目的,我试图弄清楚 SSH 协议是如何工作的。不幸的是,互联网上有一些信息(例如与 WebSocket 协议的比较),所以我关注RFC 4253 - The Secure Shell (SSH) Transport Layer Protocol。
在客户端,我使用 Git Bash(仅用于测试)和一个通过 SSH 协议工作的简单克隆命令:
git clone git@localhost:test/test.git
在服务器端,我在端口 22 上打开了 TCP 套接字,并使用以下代码 sn-p 来解析传入的数据:
public class TestSSH {
public static void main(String[] args) throws IOException{
ServerSocket server = new ServerSocket(22);
Socket client = server.accept();
InputStream inputStream = client.getInputStream();
OutputStream outputStream = client.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
PrintWriter writer = new PrintWriter(outputStream);
String versionExchange = reader.readLine();
System.out.println("VERSION EXCHANGE: " + versionExchange);
writer.println("SSH-2.0-TestSSH_1.0");
writer.flush();
int packetLength = fetchPacketLength(inputStream);
System.out.println("PACKET LENGTH: " + packetLength);
int paddingLength = inputStream.read();
System.out.println("PADDING LENGTH: " + paddingLength);
int payloadLength = packetLength - paddingLength - 1;
byte[] payload = fetch(inputStream, payloadLength);
System.out.println("PAYLOAD: " + payload.length + " bytes");
System.out.println(new String(payload, "UTF-8"));
byte[] randomPadding = fetch(inputStream, paddingLength);
System.out.println("RANDOM PADDING: " + randomPadding.length);
server.close();
}
private static int fetchPacketLength(InputStream inputStream) throws IOException{
int length = ((inputStream.read() & 0xFF) << 24);
length |= ((inputStream.read() & 0xFF) << 16);
length |= ((inputStream.read() & 0xFF) << 8);
length |= (inputStream.read() & 0xFF);
return length;
}
private static byte[] fetch(InputStream inputStream, int length) throws IOException{
byte[] buffer = new byte[length];
for (int i = 0; i < length; i++) {
buffer[i] = (byte) inputStream.read();
}
return buffer;
}
}
我在这里尝试实现的是在服务器端读取实际的 SSH 密钥以进行身份验证。
此时我有以下输出:
VERSION EXCHANGE: SSH-2.0-OpenSSH_7.1
PACKET LENGTH: 1844
PADDING LENGTH: 10
PAYLOAD: 1833 bytes
D^?>?$?? ?curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384...
RANDOM PADDING: 10
如果我理解正确 - 有效负载应该包含解密 MAC(目标 SSH 密钥)的密码,但有效负载本身是一个长字符串,它的头部已损坏,带有一些不可解码的字节,这让我觉得我做错了什么.此外,我不知道在 MAC 结束之前我应该读取多少字节。
任何帮助表示赞赏。 谢谢。
【问题讨论】:
标签: java sockets authentication encryption ssh