Skip to content

Instantly share code, notes, and snippets.

@Jiang-Xuan
Last active November 15, 2022 07:14
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jiang-Xuan/229918ec293c9e016ec4941c3bfd0af0 to your computer and use it in GitHub Desktop.
Save Jiang-Xuan/229918ec293c9e016ec4941c3bfd0af0 to your computer and use it in GitHub Desktop.
shell 登录指纹验证

在 ssh 登录远程主机的时候, 如果是第一次登录, 一般都会出现如下提示:

The authenticity of host '*.*.*.* (*.*.*.*)' can't be established.
ECDSA key fingerprint is MD5:28:00:72:3d:37:74:6c:84:6d:87:28:d4:3b:0d:ef:28.
Are you sure you want to continue connecting (yes/no)? 

该提示说明远程主机从来没有被登陆过, 无法校验远程主机的真实性, 计算出远程主机给出的 公钥 的摘要.

该指纹是怎么计算出来的?

ssh 握手过程

  • 客户端 ssh *.*.*.* 请求连接 sshd 服务
  • 服务器给客户端发公钥证书, 告诉客户端用这个公钥加密密码之后再给我发过来
  • 由于 ssh 没有 CA 证书的认证机制, 所以很容易受到 中间人 的攻击, 而客户端又是第一次收到这个公钥, 无法判断是否真实,所以计算公钥证书的摘要, 然后给出用户做选择, 这一段摘要也就是上方的 MD5:28:00:72:3d:37:74:6c:84:6d:87:28:d4:3b:0d:ef:28
  • 如果 yes, 会将该公钥保存在 ~/.ssh/known_hosts 文件中
  • 然后用该公钥加密用户输入的密码
  • 服务器收到加密的密码, 用私钥解密, 正确, 允许登录, 否则, 拒绝登录

公钥计算摘要

服务器的公私钥存放在 /etc/ssh 目录下 公钥的格式:

ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLJWpTTOyGt6kDHPOsT4oBdpoPHdwG7ExEnbTE+LyjAF2z3LtNyXUS+9qZweI6C9ICfAEffP93KXdT8S7MKhMcc=

不过公钥使用 base64 加密过的, 实际的公钥的字符都不是可见字符.

base64 解密这段字符串

> const foo = Buffer.from('AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLJWpTTOyGt6kDHPOsT4oBdpoPHdwG7ExEnbTE+LyjAF2z3LtNyXUS+9qZweI6C9ICfAEffP93KXdT8S7MKhMcc=', 'base64')
undefined
> foo
<Buffer 00 00 00 13 65 63 64 73 61 2d 73 68 61 32 2d 6e 69 73 74 70 32 35 36 00 00 00 08 6e 69 73 74 70 32 35 36 00 00 00 41 04 b2 56 a5 34 ce c8 6b 7a 90 31 ... >
> foo.toString()
'\u0000\u0000\u0000\u0013ecdsa-sha2-nistp256\u0000\u0000\u0000\bnistp256\u0000\u0000\u0000A\u0004�V�4��kz�1�:���\u0017i����n��I�LO��0\u0005�=˴ܗQ/���\u001e#�� \'\u0011���r�u?\u0012�¡1�'
> 

这才是真正的公钥! 可以用 sha256 算法或者是 md5 计算出公钥摘要, 这里计算出来的就是 shell 询问你是否接受的字符串

md5 计算出来的摘要为 MD5:28:00:72:3d:37:74:6c:84:6d:87:28:d4:3b:0d:ef:28 公钥 -> base64 反编码 -> md5 计算摘要 -> 询问用户

sha256 计算出来的摘要为 SHA256:x5+1gGhDFm+V0KUEJquNjVPUIvqTmL8TbJu7Aq+Iemg sha256 计算出来的摘要也含有不可见字符, 所以又经由 base64 编码才出来这一段字符串 公钥 -> base64 反编码 -> sha256 计算摘要 -> base64 编码 -> 询问用户

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment