【转】ssh 公钥方式认证攻略

转自:

http://hi.baidu.com/shirdrn/blog/item/523aec06fb28ae7d02088193.html

版权声明:可以任意转载,但转载时必须标明原作者charlee、原始链接http://tech.idv2.com/2006/10/21/ssh-rsa-auth/以及本声明。

前面介绍cygwin下安装sshd时简单地提到了ssh的公钥认证。下面将这种认证方式详细地解释一下。

为什么要使用公钥认证

公钥认证的原理

服务器端设置

客户端设置

Linux

Windows

使用Linux下生成的公钥和密钥的情况

使用puttygen生成公钥和密钥

设置putty使用公钥认证

为什么要使用公钥认证

通常,通过ssh登录远程服务器时,使用密码认证,分别输入用户名和密码,两者满足一定规则就可以登录。但是密码认证有以下的缺点:

用户无法设置空密码(即使系统允许空密码,也会十分危险)

密码容易被人偷窥或猜到

服务器上的一个帐户若要给多人使用,则必须让所有使用者都知道密码,导致密码容易泄露,而且修改密码时必须通知所有人

而使用公钥认证则可以解决上述问题。

公钥认证允许使用空密码,省去每次登录都需要输入密码的麻烦

多个使用者可以通过各自的密钥登录到系统上的同一个用户

公钥认证的原理

所谓的公钥认证,实际上是使用一对加密字符串,一个称为公钥(publickey),任何人都可以看到其内容,用于加密;另一个称为密钥(privatekey),只有拥有者才能看到,用于解密。通过公钥加密过的密文使用密钥可以轻松解密,但根据公钥来猜测密钥却十分困难。

ssh的公钥认证就是使用了这一特性。服务器和客户端都各自拥有自己的公钥和密钥。为了说明方便,以下将使用这些符号。

Ac客户端公钥

Bc客户端密钥

As服务器公钥

Bs服务器密钥

在认证之前,客户端需要通过某种方法将公钥Ac登录到服务器上。

认证过程分为两个步骤。

会话密钥(sessionkey)生成

客户端请求连接服务器,服务器将As发送给客户端。

服务器生成会话ID(sessionid),设为p,发送给客户端。

客户端生成会话密钥(sessionkey),设为q,并计算r=pxorq。

客户端将r用As进行加密,结果发送给服务器。

服务器用Bs进行解密,获得r。

服务器进行rxorp的运算,获得q。

至此服务器和客户端都知道了会话密钥q,以后的传输都将被q加密。

认证

服务器生成随机数x,并用Ac加密后生成结果S(x),发送给客户端

客户端使用Bc解密S(x)得到x

客户端计算q+x的md5值n(q+x),q为上一步得到的会话密钥

服务器计算q+x的md5值m(q+x)

客户端将n(q+x)发送给服务器

服务器比较m(q+x)和n(q+x),两者相同则认证成功

服务器端设置

使用公钥认证需要对服务器进行一些设置。修改/etc/sshd_config的以下配置。

RSAAuthenticationyes#启用RSA认证

PubkeyAuthenticationyes#启用公钥认证

PasswordAuthenticationno#禁止密码认证

然后重新启动sshd。

/etc/init.d/sshrestart

客户端设置

Linux

假设客户端的用户charlee要以guest用户登录到服务器上。首先在客户端执行下面的命令。

[charlee@client:~]$ssh-keygen-trsa

Generatingpublic/privatersa1keypair.

Enterfileinwhichtosavethekey(/home/charlee/.ssh/id_rsa):

Enterpassphrase(emptyfornopassphrase):输入密码

Entersamepassphraseagain:再次输入密码

Youridentificationhasbeensabedin/home/charlee/.ssh/id_rsa

Yourpublickeyhasbeensavedin/home/charlee/.ssh/id_rsa.pub

生成的文件保存在主目录的.ssh目录下,id_rsa为客户端密钥,id_rsa.pub为客户端公钥。

之后,通过U盘等方式将公钥id_rsa.pub复制到服务器上,并执行下列命令。

[guest@server:~]$catid_rsa.pub>>.ssh/authorized_keys

其中id_rsa.pub是客户端的用户charlee的公钥。

这样在客户端即可通过以下的命令连接服务器。

[charlee@client:~]$ssh-lguestserver

若不想每次登录服务器时都输入密码,可以先执行下列命令:

[charlee@client:~]$ssh-add

Enterpassphrasefor/home/charlee/.ssh/id_rsa:输入密码

Identityadded:/home/charlee/.ssh/id_rsa(/home/charlee/.ssh/id_rsa)

以后登录服务器就不需要输入密码了。

Windows

假设我们使用putty连接ssh服务器。为了使用公钥认证,我们需要同时下载puttygen这个工具来生成putty所使用的密钥。

使用Linux下生成的公钥和密钥的情况

如果你按照上面的介绍,在Linux下生成了公钥和密钥的话,那么需要利用puttygen将密钥转换成putty使用的格式。

将Linux下生成的密钥id_rsa复制到Windows下。启动puttygen,然后单击Load按钮,选择文件类型为所有文件,然后选择id_rsa,打开。若在生成密钥时输入了密码,则打开时需要输入该密码。之后就可以在puttygen的主界面上单击Saveprivatekey,保存成putty格式的密钥。

使用puttygen生成公钥和密钥

你也可以利用puttygen直接生成公钥和密钥。打开puttygen,然后在画面下方的Parameters栏选择加密算法和加密长度(一般取默认值即可),最后单击Generate。画面上会出现一个进度条,在界面上随意移动鼠标以生成随机数。最后提示生成结束,单击Saveprivatekey按钮保存密钥。最后将上方的PublickeyforpastingintoOpenSSHauthorized_keysfile栏中的内容复制到Linux下用户主目录下的~/.ssh/authorized_keys文件中。

设置putty使用公钥认证

先在putty中设置好连接的主机名、端口等信息(说明省略)。使用公钥认证需要设置两个地方:一个是Connection中的Auto-loginusername,输入在服务器上的用户名;另一个是Connection->SSH->Auth中的Privatekeyfileforauthentication,选择刚才转换或生成的.ppk格式的密钥。之后即可使用公钥认证进行连接了。

个人理解与总结:

1、客户端与服务器端使用公钥加密

将服务器端与客户端作为两个通讯的双方:

首先,客户端请求连接服务器,服务器向客户端发送客户端公钥;

接着,生成客户端会话密钥,即私钥。因为客户端和服务器端都需要知道客户端私钥,并且客户端私钥是根据会话ID在客户端生成,会话ID为p,所以需要将客户端私钥加密传输至服务器端。这里,先对客户端私钥进行了XOR操作,即r=pxorq,r再次使用服务器端公钥进行加密发送到服务器端,服务器端可以使用服务器端私钥进行解密,从而获取到客户端私钥。

然后服务器端和客户端可以进行数据的安全传送了。

1、客户端与服务器端使用公钥认证

加密并不能保证通讯中传送数据发送方身份的真实性,需要进行认证。

首先,服务器端通过生成一个随机数并使用客户端公钥进行加密后,发送到客户端,客户端自然使用客户端私钥进行解密获取随机数的值;

接着,客户端和服务器端都已经知道此次生成的随机数,再在双方都知道客户端私钥的基础上,进行运算求得(客户端密钥+随机数)的MD5值;

然后,因为客户端计算的MD5值实在客户端进行的,而验证是在服务器端,所以客户端需要将自己的计算的MD5值发送给服务器端,在发送之前要进行加密的;

最后,服务器端解密客户端发送的MD5值,与在服务器端计算的MD5值进行比较,如果相等,则认证通过。

相关推荐