SSH的通讯和认证

摘要:
大多数文档都没有将SSH的连线加密通讯和SSH的登录加密认证特别地区分来讲,对于我这种对密钥不太熟悉的人来说常常引起一些歧义。

SSH的通讯和认证

转自:http://blog.sina.com.cn/s/blog_4e9440910100zxk0.html

之前一直对SSH的认证模棱两可,今天对SSH的通讯,认证和配置有了进一步的学习。

大多数文档都没有将SSH的连线加密通讯和SSH的登录加密认证特别地区分来讲,对于我这种对密钥不太熟悉的人来说常常引起一些歧义。

首先,必须把通讯和认证区分开来。通讯加密是为了确保通讯连接建立之后client和server之间相互发送的信息都是经过特定加密的,其它人得到消息也无法获取消息内容,它贯穿于整个通讯过程,在会话密钥生成前使用的是非对称密钥,在会话密钥建立之后的通讯都使用的是会话密钥(使用会话密钥速度更快,生成后取代非对称密钥进行加解密)。认证加密是为了替代传统的手工输入密码认证的一种备选认证方式,它和密码登陆有着相同的目标:服务器认同客户端的身份并允许客户端用户登陆,它的作用也是暂时性的,在用户认证成功之后就不再需要了。

对于通讯信息的加密,首先是建立会话密钥(对称密钥)的过程,鸟哥:“目前常見的網路封包加密技術通常是藉由所謂的『非對稱金鑰系統』來處理的。主要是透過兩把不一樣的公鑰與私鑰(Public and Private Key)組合成為一把獨一無二的金鑰(key pair)後,利用這把金鑰來進行資料的加解密工作。”如下图所示,伺服器和用户端都对发送的消息用公钥加密,对接收到的消息用私钥解密。要让解密成功,就必须保证私钥与公钥是匹配的!这里的匹配是指,只需要下图中上方的公钥和私钥是匹配的,下方的公钥和私钥也是匹配的,即一对密钥负责一个方向的消息加密和解密。当然有可能的话也可以只使用一对密钥(即图中两个公钥是相同的,两个私钥也是相同的),即一对密钥负责双向的加密和解密。(两种配对方式如何选取?我认为用一对密钥比较简单吧,本文介绍的SSH会话用的是对称密钥,不涉及到这个问题。)

由于公钥和私钥的算法之间存在特殊的数学关系,从而使得这种配对成为可能。密钥对在数学上彼此相关,例如,配合使用密钥对可以实现两次使用对称密钥的效果。密钥必须配合使用:不能使用每个单独的密钥来撤消它自己的操作。这意味着每个单独密钥的操作都是单向操作:不能使用一个密钥来撤消它的操作。此外,设计两个密钥使用的算法时,特意设计无法使用一个密钥确定密钥对中的另一个密钥。因此,不能根据公钥确定出私钥。但是,使得密钥对成为可能的数学原理也使得密钥对具有对称密钥所不具有的一个缺点。这就是,所使用的算法必须足够强大,才能使人们无法通过强行尝试,使用已知的公钥来解密通过它加密的信息。公钥利用数学复杂性以及它的单向特性来弥补它是众所周知的这样一个事实,以防止人们成功地破解使用它编码的信息。【摘自http://technet.microsoft.com/zh-cn/library/aa998077(EXCHG.65).aspx】

SSH的通讯和认证
1来源于鸟哥的私房菜-SSH

在整个通讯过程中,为实现SSH的安全连接,服务器端与客户端要经历如下五个阶段:

n版本号协商阶段SSH目前包括SSH1和SSH2两个版本,双方通过版本协商确定使用的版本

n密钥和算法协商阶段SSH支持多种加密算法,双方根据本端和对端支持的算法,协商出最终使用的算法

n认证阶段SSH客户端向服务器端发起认证请求,服务器端对客户端进行认证

n会话请求阶段,认证通过后,客户端向服务器端发送会话请求

n交互会话阶段,会话请求通过后,服务器端和客户端进行信息的交互

1.版本号协商阶段

整个阶段都是明文传输的:

1.服务器打开端口22,等待客户端连接。

2.客户端向服务器端发起TCP初始连接请求,TCP连接建立后,服务器向客户端发送第一个报文,包括版本标志字符串,格式为“SSH-<主协议版本号>.<次协议版本号>-<软件版本号>”,协议版本号由主版本号和次版本号组成,软件版本号主要是为调试使用。

3.客户端收到报文后,解析该数据包,如果服务器端的协议版本号比自己的低,且客户端能支持服务器端的低版本,就使用服务器端的低版本协议号,否则使用自己的协议版本号。

4.客户端回应服务器一个报文,包含了客户端决定使用的协议版本号。服务器比较客户端发来的版本号,决定是否能同客户端一起工作。

5.如果协商成功,则进入密钥和算法协商阶段,否则服务器端断开TCP连接。

2.密钥和算法协商生成会话密钥

下面来讲一下SSH的通讯加密建立的过程(参考http://fly-net-cn.iteye.com/blog/119248

1.服务器端sshd在启动时生成自己密钥对(pub-s/ppk-s…),如果之前有档案的话可以直接使用。

2.客户端请求连接。【明文】

3.服务器端发送自己的主机公钥,服务公钥和8个字节的cookie给客户端。【明文】

4.客户端立即把从服务器端收到cookie、主机密钥、和服务密钥作为参数计算出会话号(计算方法和服务器端生成会话号的方法相同,所以两者的会话号也是相同的,这为会话密钥相同提供了前提条件),并用会话号的前16字节随机数的前16字节异或后生成一个值x,用服务器端公钥pub-s加密x,发送给服务器。【pub-s加密】

5.客户端记录服务器端的公钥(人为检查服务器公钥的指纹码的正确性,可以看作client端的自我保护),追加在~/.ssh/known_hosts文件中。

6.服务器用自己的主机私钥和服务私钥解密出x,同样异或会话号的前16字节之后就获得客户端的产生的随机数的前16字节,它就是会话密钥!

7.加密连接建立。使用统一的会话密钥进行双向的加密和解密。服务器首先给用户端发送加密的包,通知服务器收到了客服端前面发送的包。下面就是客户端的认证过程了。

总结起来就是要交换确定会话号和会话密钥(交换信息,生成会话号和会话密钥的详细算法常见http://fly-net-cn.iteye.com/blog/119248)。在实际传送信息时采用对称密钥加密算法,而不采用公开密钥加密算法(RSA/DSA等),因为公开密钥算法(加密&解密)速度较慢。在大多数对称算法中,加密密钥和解密密钥是相同的,都是进行xor计算。会话密钥只使用于通信期间,下次通信再重新启用一个新的会话密钥。

通过以上步骤,服务器端和客户端就取得了相同的会话密钥和会话ID。

u对于后续传输的数据,两端都会使用会话密钥进行加密和解密,保证了数据传送的安全

u在认证阶段,两端会使用会话ID用于认证过程。

3.认证阶段

连接建立之后,客户端的认证步骤:

1.客户端向服务器发送认证请求,包含自己的用户名等。

2.服务器检查本地档案,用户不存在,返回错误信息SSH_SMSG_FAILURE包;用户存在且不需要认证,返回认证成功SSH_SMSG_SUCCESS包;用户存在且需要认证,则通知用户端进行认证,返回支持的认证方式。前两种情况下直接跳到第5步。

3.客户端接收到认证消息后,不停地向服务器发包申请用各种不同的方法进行认证(认证交互过程后文有介绍),直到时限已到服务器关闭连接为止。

4.服务器根据认证消息返回认证结果,对任何一个申请,如果服务器接受,就以SSH_SMSG_SUCCESS包回应。如果不接受,或者是无法识别,则以SSH_SMSG_FAILURE包回应。

5.如果认证通过,客户端向服务端提交会话请求,服务器则进行等待,处理客户端的请求。会话请求分为这样几类:申请对数据传送进行压缩、申请伪终端、启动X11、TCP/IP端口转发、启动认证代理、运行shell、执行命令。

具体的认证方式有三种:

1.密码认证

只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击。

2.RSA认证与DSA认证

a)客户端先为自己创建一对密匙,并把公匙放在需要访问的服务器上

b)客户端会向服务器发出请求,请求用你的密匙进行安全验证;

c)服务器收到请求之后,在该服务器目录下寻找公匙,然后把它和你发送过来的公匙进行比较。若两密匙一致,服务器就用公匙加密“质询”(challenge)(一个随机数)并把它发送给客户端;

d)客户端收到“质询”之后就可以用私钥解密后,再把这个随机数发送给服务器。

e)服务器检查接收到的数和之前自己生成的随机数是不是相同的,如果相同,服务器就认为客户端确实有匹配的专用密钥,它能成功的对服务器的消息进行解密!

4.会话请求阶段

1.服务器等待客户端的请求;

2.认证通过后,客户端向服务器发送会话请求;

3.服务器处理客户端的请求。请求被成功处理后,服务器会向客户端回应SSH_SMSG_SUCCESS包,SSH进入交互会话阶段;否则回应SSH_SMSG_FAILURE包,表示服务器处理请求失败或者不能识别请求。

5.交互会话阶段

在这个模式下,数据被双向传送(由会话密钥加解密):

1.客户端将要执行的命令加密后传给服务器;

2.服务器接收到报文,解密后执行该命令,将执行的结果加密发还给客户端;

3.客户端将接收到的结果解密后显示到终端上.

参考文献:

http://www.ibm.com/developerworks/cn/linux/security/openssh/part1/index.html(推荐)

http://fly-net-cn.iteye.com/blog/119245(推荐)

http://blog.csdn.net/oncoding/article/details/4365062(推荐)

http://technet.microsoft.com/zh-cn/library/aa998077(EXCHG.65).aspx

http://blog.csdn.net/oncoding/article/details/4365062

http://club.aofix.com/forum.php?mod=viewthread&tid=12257

http://linux.vbird.org/linux_server/0310telnetssh.php#ssh_secure

http://jiajun.iteye.com/blog/621309


SSH的一些技巧

1.sftp & scp

SSH除了提供远程登录终端的功能外,还提供sftp-server。当你想要从远端伺服器下载或上传档案就必須要使用sftp或scp。

2.免询问登陆

如果客户端没有保存服务器的公钥,客户端程序会询问用户是否添加当前服务器的公钥到known_hosts文件中。在大量登陆和使用脚本登陆的情况下,想采用免询问的登陆方式可以采用以下方法:

ssh -o StrictHostKeyChecking=no root@hostip

3.免密码登陆(RSA认证方式)

先理解前面“认证阶段”的认证方式,主要思想就是在客户端生成自己的密钥对,将公钥添加到服务器端的~/.ssh/ authorized_keys文件末尾。

ssh-keygen [-t rsa|dsa]

可选加密方式有rsa和dsa,默认为rsa。如果设置密码那么在认证时客户端这边需要输入该密码,用于开启私钥解密。

默认生成的目录在~/.ssh/下的id_rsa(私钥)和id_rsa.pub(公钥),可以更改。

拷贝到目标服务器上:

scp ~/.ssh/id_rsa.pub user@hostip:~

追加公钥到authorized_keys文件中:

cd !/.ssh && cat id_rsa.pub >> .ssh/authorized_keys

4.SSH反应缓慢的问题

设置sshd_config中UseDNS为no。详细可参见博客。

http://blog.sina.com.cn/s/blog_4e9440910100zn28.html

免责声明:文章转载自《SSH的通讯和认证》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SSH框架使用注解简化代码wsdl详解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

sshd服务启动失败问题

 查看/etc/ssh/ssh_host_ed25519_key权限是755,其他用户也有访问权限,修改该文件权限为600后,重启sshd服务成功 启动后,发现/etc/ssh/ssh_host_rsa_key和/etc/ssh/ssh_host_ecdsa_key文件也是755权限,也需要修改为600权限 # systemctl status ssh...

Python之路【第七篇】python基础 之socket网络编程

本篇文章大部分借鉴http://www.cnblogs.com/nulige/p/6235531.htmlpython socket 网络编程一、服务端和客户端 BS架构 (腾讯通软件:server+client) CS架构 (web网站) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二、OSI七层模型 互联网协议按...

关于c# dll版本号的修改方法

方法都是从网上找到的,自己把使用过的记录下,以备回忆。 程序集版本有4部分组成, // 主版本 // 次版本 // 内部版本号// 修订号 方法1:打开 类库对应的 AssemblyInfo.cs 文件            1.注释[assembly: AssemblyFileVersion("1.0.0.0")]            2.[asse...

Linux系统中imp导入dmp文件

[oracle@ocm1 ~]$ lltotal 32-rw-r--r-- 1 oracle oinstall 24576 Mar 27 15:26 COUNTRIES.dmpdrwxr-xr-x 2 oracle oinstall  4096 Mar 27 12:39 scriptdrwxr-xr-x 2 oracle oinstall  4096 Ma...

【Git&amp;amp;GitHub idea中使用Git 03】

在Idea中使用Git 一、全局配置 1、首先按照Git的核心程序(客户端) 2、查看git是否安装成功:git  --version 3、查看git安装的路径:which git   4、idea中打开Preferences -->Version Control --> Git --> 按下图进行配置  5、idea中配置GitHub...

网络编程bind函数详解(转载)

注:该文转载自https://blog.csdn.net/zpznba/article/details/90763798 bind 函数如何选择绑定地址 我们知道bind函数一般用在服务器代码中: struct sockaddr_in bindaddr; bindaddr.sin_family = AF_INET; bindaddr.sin_addr.s_...