ssh是什么协议.docx
《ssh是什么协议.docx》由会员分享,可在线阅读,更多相关《ssh是什么协议.docx(11页珍藏版)》请在冰点文库上搜索。
![ssh是什么协议.docx](https://file1.bingdoc.com/fileroot1/2023-7/2/1bd83655-f20e-486d-9c41-a197dd192dc3/1bd83655-f20e-486d-9c41-a197dd192dc31.gif)
ssh是什么协议
竭诚为您提供优质文档/双击可除
ssh是什么协议
篇一:
ssh使用及协议分析
ssh使用及协议分析
ssh是一个用来替代telnet、Ftp以及R命令的工具包,主要是想解决口令在网上明文传输的问题。
为了系统安全和用户自身的权益,推广ssh是必要的。
ssh有两个版本,我们现在介绍的是版本2。
一、安装ssh
具体步骤如下:
获得ssh软件包。
(ftp:
//:
/pub/unix/ssh-2.3.0.tar.gz)
成为超级用户(root).
#gzip–cdssh-2.3.0.tar.gz|tarxvf–
#cdssh-2.3.0
#./configure
注意,如果你希望用tcp_wrappers来控制ssh,那么在configure时需要加上选项“--with-libwrap=/path/to/libwrap/”,
用来告诉ssh关于libwrap.a和tcpd.h的位置。
#make
#makeinstall
和ssh有关的程序都放置在/usr/local/bin下,包括ssh,sftp,sshd2,ssh-keygen等。
二、配置
ssh的配置文件在/etc/ssh2下,其中包括sshd2的主机公钥和私钥:
hostkey和hostkey.pub。
这两个文件通常是在安装ssh时自动生成的。
你可以通过下面的命令重新来生成它们:
#rm/etc/ssh2/hostkey*
#ssh-keygen2–p/etc/ssh2/hostkey
而ssh2_config文件一般情形下无需修改。
三、启动sshd2
每个要使用ssh的系统都必须在后台运行sshd2。
用手工启动:
#/usr/local/bin/sshd2
2.服务器向客户端发送第一个报文,宣告自己的版本号,包括协议版本号和软件版本号。
协议版本号由主版本号和次版本号两部分组成。
它和软件版本号一起构成形如:
"ssh-.-\n"
的字符串。
其中软件版本号字符串的最大长度为40个字节,仅供调试使用。
3.客户端接到报文后,回送一个报文,内容也是版本号。
客户端响应报文里的协议版本号
这样来决定:
当与客户端相比服务器的版本号较低时,如果客户端有特定的代码来模拟,则它发送较低的版本号;如果它不能,则发送自己的版本号。
当与客户端相比服务器的版本号较高时,客户端发送自己的较低的版本号。
按约定,如果协议改变后与以前的相兼容,主协议版本号不变;如果不相兼容,则主协议版本号升高。
4.服务器接到客户端送来的协议版本号后,把它与自己的进行比较,决定能否与客户端一
起工作。
如果不能,则断开tcp连接;
5.如果能,则按照二进制数据包协议发送第一个二进制数据包,双方以较低的协议版本来
一起工作。
到此为止,这
6.两个报文只是简单的字符串,你我等凡人直接可读。
第二阶段:
7.协商解决版本问题后,双方就开始采用二进制数据包进行通讯。
由服务器向客户端发送
第一个包,内容为自己的Rsa主机密钥(hostkey)的公钥部分、Rsa服务密钥(serverkey)的公钥部分、支持的加密方法、支持的认证方法、次协议版本标志、以及一个64位的随机数(cookie)。
这个包没有加密,是明文发送的。
8.客户端接收包后,依据这两把密钥和被称为cookie的64位随机数计算出会话号(session
id)和用于加密的会话密钥(sessionkey)。
随后客户端回送一个包给服务器,内容为选用的加密方法、cookie的拷贝、客户端次协议版本标志、以及用服务器的主机密钥的公钥部分和服务密钥的公钥部分进行加密的用于服务器计算会话密钥的32字节随机字串。
除这个用于服务器计算会话密钥的32字节随机字串外,这个包的其他内容都没有加密。
之后,双方的通讯就是加密的了,
9.服务器向客户端发第二个包(双方通讯中的第一个加密的包)证实客户端的包已收到。
第三阶段:
双方随后进入认证阶段。
可以选用的认证的方法有:
(1)~/.rhosts或/etc/hosts.equiv认证(缺省配置时不容许使用它);
(2)用Rsa改进的~/.rhosts或/etc/hosts.equiv认证;
(3)Rsa认证;
(4)口令认证。
如果是使用~/.rhosts或/etc/hosts.equiv进行认证,客户端使用的端口号必须小于1024。
10.认证的第一步是客户端向服务器发ssh_cmsg_useR包声明用户名,服务器检查该用户
是否存在,确定是否需要进行认证。
11.如果用户存在,并且不需要认证,服务器回送一个ssh_smsg_success包,认证完成。
否则,服务器会送一个ssh_smsg_FailuRe包,表示或是用户不存在,或是需要进行认证。
注意,如果用户不存在,服务器仍然保持读取从客户端发来的任何包。
除了对类型为ssh_msg_disconnect、ssh_msg_ignoRe以及ssh_msg_debug的包外,对任何类型的包都以ssh_smsg_FailuRe包。
用这种方式,客户端无法确定用户究竟是否存在。
12.如果用户存在但需要进行认证,进入认证的第二步。
客户端接到服务器发来的
ssh_smsg_FailuRe包后,不停地向服务器发包申请用各种不同的方法进行认证,直到时限已到服务器关闭连接为止。
时限一般设定为5分钟。
13.对任何一个申请,如果服务器接受,就以ssh_smsg_success包回应;如果不接受,
或者是无法识别,则以ssh_smsg_FailuRe包回应。
第四阶段:
14.认证完成后,客户端向服务器提交会话请求。
15.服务器则进行等待,处理客户端的请求。
在这个阶段,无论什么请求只要成功处理了,
服务器都向客户端回应ssh_smsg_success包;否则回应ssh_smsg_FailuRe包,这表示或者是服务器处理请求失败,或者是不能识别请求。
会话请求分为这样几类:
申请对数据传送进行压缩、申请伪终端、启动x11、tcp/ip端口转发、启动认证代理、运行shell、执行命令。
16.到此为止,前面所有的报文都要求ip的服务类型(tos)使用选项iptos
_thRoughput。
第五阶段:
17.会话申请成功后,连接进入交互会话模式。
在这个模式下,数据在两个方向上双向传送。
18.此时,要求ip的服务类型(tos)使用iptos_lowdelay选项。
19.当服务器告知客户端自己的退出状态时,交互会话模式结束。
20.(注意:
进入交互会话模式后,加密被关闭。
在客户端向服务器发送新的会话密钥后,
加密重新开始。
用什么方法加密由客户端决定。
)
第二部分:
密钥的交换和加密的启动
在服务器端有一个主机密钥文件,它的内容构成是这样的:
1)私钥文件格式版本字符串;
2)加密类型(1个字节);
3)保留字(4个字节);
4)4个字节的无符号整数;
5)mp型整数;
6)mp型整数;
7)注解字符串的长度;
8)注解字符串;
9)校验字(4个字节);
10)mp型整数;
11)mp型整数;
12)mp型整数;
13)mp型整数;
其中4、5、6三个字段构成主机密钥的公钥部分;10、11、12、13四个字段构成主机密
篇二:
ssh协议
ssh协议
ssh为secureshell的缩写,由ietF的网络工作小组所制定,ssh为建立在应用层和传输层上的安全协议,ssh是目前交可靠,专为远程登录服务器提供安全性的协议。
利用ssh协议可以有效防止远程管理过程中的信息泄漏问题。
ssh也俗称三层构架
第一层:
实体类层
第二层:
业务逻辑层
第三层:
表示层(先是层)
ssh的安全验证工作原理
从客户端来看,ssh提供两种级别的安全验证
第一种级别(基于口令的安全验证)只要知道自己的张哈和口令,就可以登录到远程主机。
所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器,可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击。
第二种级别(基于密钥的安全验证)需要依靠密钥,也就是你必须为在即创建一堆密钥,并把公用密钥放在安全访问的服务器上,如果你要连接到ssh服务器上,客户端软件就会向服务器发出请求,请求用你的密钥进行安全验证。
服务器收到请求之后,先在你在该服务器的目录下寻找你的公用密钥,然后把它和你发送过来的公用密钥进行比较。
如果两个密钥一致,服务器就用公用密钥一致加密“质询”(challenge)并把它发送给客户端软件。
客户端软件收到“质询”之后可以用你的私人密钥解密再把它发送给服务器。
用这种方式必须知道自己密钥的口令。
但是,与第一种级别相比,第二种级别不需要在网络上传送口令。
第二种级别不仅加密所偶传送的数据,而且“中间人”这种攻击方式也是不可能的(因为他没有你的私人密钥)但是整个登录过程可能需要10秒。
ssh分为两部分:
客户端部分和服务端部分
服务端是一个守护进程(demon),它在后台运行并响应来自来自客户端的连接请求,服务端一般是sshd进程,提供了对远程连接的处理,一般包括公共密钥认证、密钥交换、对称密钥加密和安全连接
客户端包含ssh程序以及像scp(远程拷贝),slogin(远程登录)sftp(安全文件传输)等其他的应用程序
他们的工作机制大致是本地的客户端发送一个连接请求到远程的服务端。
服务端检查社情的包和ip地址再发送密钥给ssh的客户端,再将密钥发回给服务端,自此连接建立。
篇三:
基于ssh协议的sftp协议
.sftp;
importjava.io.File;
importjava.io.Fileinputstream;
importjava.io.Fileoutputstream;
importjava.util.hashmap;
importjava.util.map;
importjava.util.properties;
importjava.util.Vector;
importcom.jcraft.jsch.channel;
importcom.jcraft.jsch.channelsftp;
importcom.jcraft.jsch.jsch;
importcom.jcraft.jsch.jschexception;
importcom.jcraft.jsch.session;
importcom.jcraft.jsch.sftpexception;
publicclasssFtptool{
privatesessionsession;
privatechannelchannel;
privatechannelsftpsftp;//sftp操作类
//privateinputstreamin;//输入流
//privateoutputstreamout;//输出流
publicsFtptool(stringhost,intport,stringusername,stringpassword)throwsexception{
getconnect(host,port,username,password);
}
/**
*连接sftp服务器
*
*@paramhost主机
*@paramport端口
*@paramuname用户名
*@paramusername密码
*@return
*@throwsexception
*/
publicchannelsftpgetconnect(stringhost,intport,stringusername,stringpassword)throwsexception{
jschjsch=newjsch();
this.session=jsch.getsession(username,host,port);
session.setpassword(password);
propertiesconfig=newproperties();
config.put("stricthostkeychecking","no");//不验证hostkeysession.setconfig(config);
try{
session.connect();
}catch(exceptione){
if(session.isconnected())
session.disconnect();
thrownewexception("连接服务器失败,请检查主机["+host+"],端口["+port
+"],用户名["+username+"],端口["+port+"]是否正确,以上信息正确的情况下请检查网络连接是否正常或者请求被防火墙拒绝.");
}
channel=session.openchannel("sftp");
try{
channel.connect();
}catch(exceptione){
if(channel.isconnected())
channel.disconnect();
thrownewexception("连接服务器失败,请检查主机["+host+"],端口["+port
+"],用户名["+username+"],密码["+password+"]是否正确,以上信息正确的情况下请检查网络连接是否正常或者请求被防火墙拒绝.");
}
this.sftp=(channelsftp)channel;
returnsftp;
}
/**
*断开连接
*/
publicvoiddisconn(){
if(null!
=this.sftp){
this.sftp.disconnect();
this.sftp.exit();
this.sftp=null;
}
if(null!
=this.channel){
this.channel.disconnect();
this.channel=null;
}
if(null!
=this.session){
this.session.disconnect();
this.session=null;
}
}
/**
*上传文件
*
*@paramdirectory上传的目录
*@paramuploadFile要上传的文件
*@paramsftp
*/
publicvoidupload(stringdirectory,stringuploadFile){//channelsftpsftp=map.keyset().iterator().next();
//sessionsession=map.get(sftp);
try{
sftp.cd(directory);
Filefile=newFile(uploadFile);
sftp.put(newFileinputstream(file),file.getname());}catch(exceptione){
e.printstacktrace();
}finally{
disconn();
}
}
/**
*下载文件
*
*@paramdirectory下载目录
*@paramdownloadFile下载的文件
*@paramsaveFile存在本地的路径
*@paramsftp
*/
publicvoiddownload(stringdirectory,stringdownloadFile,stringsaveFile){
//channelsftpsftp=map.keyset().iterator().next();
try{
sftp.cd(directory);
Filefile=newFile(saveFile);
sftp.get(downloadFile,newFileoutputstream(file));
}catch(exceptione){
e.printstacktrace();
}finally{
disconn();
}
}
/**
*删除文件
*
*@paramdirectory要删除文件所在目录
*@paramdeleteFile要删除的文件
*@paramsftp
*/
publicvoiddelete(stringdirectory,stringdeleteFile){//channelsftpsftp=map.keyset().iterator().next();
try{
sftp.cd(directory);
sftp.rm(deleteFile);
}catch(exceptione){
e.printstacktrace();
}finally{
disconn();
}
}
/**
*列出目录下的文件
*
*@paramdirectory要列出的目录
*@paramsftp
*@return
*@throwssftpexception
*/
publicVectorlistFiles(stringdirectory)
throwssftpexception{
//channelsftpsftp=map.keyset().iterator().next();
Vectorvec=sftp.ls(directory);
disconn();
returnvec;
}
/**
*用于查询某个远程目录下的文件名称
*@paramdirectory远程目录
*@paramvalistr
*@parammap
*@return
*@throwssftpexception
*/
publicVectorlistFilenames(stringdirectory,stringvalistr)
throwssftpexception{
Vectorret=newVector();
//channelsftpsftp=map.keyset().iterator().next();
system.out.println("------");
for(objectobj:
sftp.ls(directory)){
stringcurstr=obj.tostring();
curstr=curstr.substring(curstr.lastindexof("")+1);
if(curstr.contains(valistr)){
ret.add(curstr);
//system.out.println(curstr);
}
}
disconn();
returnret;
}
publicstaticvoidmain(string[]args){
stringip="134.128.176.29";
stringuname="phs";
stringpwd="123456";
intpoRt=22;
stringpath="/u1/phs/Rnms/paramfile";
sFtptooltool=null;
Vectorvector=null;
try{
tool=newsFtptool(ip,poRt,uname,pwd);
//mapmap=tool.getconnect(ip,poRt,uname,pwd);
vector=tool.listFilenames(path,".xml");
}catch(exceptione){
//todoauto-generatedcatchblock
e.printstacktrace();