在服务器端有一个主机密钥文件,它的内容构成是这样的:
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 四个字段构成主机密钥的私钥部分。9、10、11、12、13 五个字段用字段 2 的加密类型标记的加密方法进行了加密。4 个字节的校验字交叉相等,即第一个字节与第三个字节相等,第二个字节与第四个字节相等。在服务器读取这个文件时进行这种交叉相等检查,如果不满足这个条 件,则报错退出。
服务器程序运行的第一步,就是按照上面的字段划分读取主机密钥文件。随后生成一个随机数,再调用函数
void rsa_generate_key(RSAPrivateKey *prv,RSAPublicKey *pub, RandomState *state,unsigned int bits);
生成服务密钥,服务密钥也由公钥和私钥两部分组成。上面的这个函数第一个指针参数指向服务密钥的私钥部分,第二个指向公钥部分。然后把主机密钥的公钥部分和 服务密钥的公钥部分发送给客户端。在等到客户端回应的包后,服务器用自己的主机密钥的私钥部分和服务密钥的私钥部分解密得到客户端发来的 32 字节随机字串。然后计算自己的会话号,并用会话号的前 16字节 xor 客户端发来的 32 字节随机字串的前 16 字节,把它作为自己的会话密钥。注意,服务器把8个字节的 cookie、主机密钥的公钥部分、和服务密钥的公钥部分作为参数来计算自己的会话号。
再来看客户端。客户端启动后的第一步骤也是读取主机密钥。然后等待服务器主机密钥、服务密钥、和 8个字节的cookie。注意,服务器发送来的只是主机密钥和服务密钥的公钥部分。接到包后,客户端立即把从服务器端收到cookie、主机密钥、和服务 密钥作为参数计算出会话号。从上面可以看出,服务器和客户端各自计算出的会话号实际是一样的。
随后,客户端检查用户主机列表和系统主机列 表,查看从服务器收到的主机密钥是否在列表中。如果不在列表中,则把它加入列表中。然后就生成 32 字节的随机字串,这个32 字节的随机字串就是客户端的会话密钥。客户端用 16字节的会话密钥 xor 它的前 16 字节,把结果用服务器的主机密钥和服务密钥进行双重加密后发送给服务器。产生 32字节随机字串时,随机数种子由两部分组成,其中一部分从系统随机数种子文件中得到,这样来避免会话密钥被猜出。从上面服务器和客户端各自计算会话密钥 的过程可以看出,服务器和客户端计算出的会话密钥是一样的。
上面的这几步,总结起来就要交换确定会话密钥,因为无论是 des、idea、3des、arcfour、还是 blowfish 都是对称加密方法,只有一把密钥,双方都知道了会话密钥才能启动加密。但会话密钥不能在网络上明文传送,否则加密就失去意义了。于是使用 RSA 公钥体系对会话密钥进行加密。
RSA 公钥体系的办法是用公钥加密私钥解密,它依据这样的数学定理:
若 p、q 是相异的两个质数,整数 r 和 m 满足
rm == 1 (mod (p-1)(q-1))
a 是任意的整数,整数 b、c 满足 b == a^m (mod pq),
c == b^r (mod pq)。则
c == a (mod pq)。
具体实现是这样的:
(1) 找三个正整数 p、q、r,其中 p、q 是相异的质数,r 是与(p-1)、(q-1)互质的数。
这三个数 p、q、r就是私钥(private key)。
(2) 再找一个正整数 m 满足 rm == 1 (mod(p-1)(q-1))。
计算 n = pq,m、n 就是公钥(public key)。
(3) 被加密对象 a 看成是正整数,设 a < n。若 a >= n,将 a 表示成 s (s < n,通常取 s = 2^t) 进制的,
然后对每一位分别编码。
(4) 加密:计算 b == a^m (mod n) (0 <= b < n),b 为加密结果。
(5) 解密:计算 c == b^r (mod n) (0 <= c < n),c 为解密结果。
从上面的数学定理可知,最后结果 c = a。
服务密钥生成后,服务器发送一个包把两把密钥发送给客户端,一个是主机密钥的公钥,另一个是服务密钥的公钥。跟随这个包一起发送的还有服务器支持的加密类 型和8个字节即64位的随机字串 cookie。客户端依据这两把密钥计算会话号,会话号长16字节即128位。计算方法是:
会话号 = MD5(主机公钥模数 n || 服务公钥模数 n || cookie)
随后客户端计算会话密钥,计算过程是首先生成32个字节即256位随机字串,然后用16字节的会话号 xor 这32字的随机字串的前16字节,并安 msb 次序来排列构成一个MP型整数,把结果发给服务器。在用服务器发来主机公钥和服务公钥对这个MP型整数作两次 RSA 加密后,客户端发一个包把这个MP型整数交给服务器。跟随这个包一起还有客户端选定的加密类型。注意,在客户端,它用上面最初的32字节随机串 session_key 来作为会话密钥进行加密,而不是发给服务器的会话密钥 key。
服务器接到上面MP型整数后,把它转换成32字节即256位的字串。再用自己计算出的16字节的会话号xor 这个字串的前16字节,把结果作为会话密钥。服务器计算自己的16字节会话号时也是把发给客户端的主机公钥、服务公钥、和16字节随机串 cookie 作为输入,因此它计算出的会话号与客户端计算出的一样。
在这之后,所有的数据传输都用选用客户端指定的加密方法进行加密了,加密时使用上面的会话密钥。
ssh 声称避免了 IP 欺骗,使用的方法在上面的密钥交换中服务器给客户端发了一个64位 cookie,要求客户端原样拷贝送回。看不出这能避免 IP 欺骗。
分享到:
相关推荐
在 DH 密钥交换结束时,两方将就用于加密和解密数据的对称密钥达成一致。 在实现 TLS 时,理解密钥交换概念很重要。 该存储库包含正在积极开发的材料,用于在面对面的谈话或研讨会的背景下演示 DH 密钥交换。 该...
sh脚本启动java -jar
startup.sh linux 启动jar包命令startup.sh linux 启动jar包命令startup.sh linux 启动jar包命令startup.sh linux 启动jar包命令startup.sh linux 启动jar包命令
linux通用版本jar启动脚本傻瓜式启动 sh run.sh start 启动 sh run.sh stop 停止 nohup java -jar XXX.jar & nohup 意思是不挂断运行命令,当账户退出或终端关闭时,程序仍然运行
linux服务器,springboot,spring cloud、spring cloud alibaba等项目启动脚本 下载脚本, 1,上传脚本至jar包同级目录 2,更改脚本: jar包名称 项目文件路径 日志路径(包含日志名称) 脚本已配置好jvm优化...
SH512加密,可以选择多次加密 注意在WIN8.1,装了VS2013下运行通过
启动服务
本zip包含2个文件一个现成的执行文件模板,一个模板命令详解,通过这个文件可以管理jar等程序的执行、关闭等
SH1+MD5加密类 //MD5 static public string MD5_Hash(string str_md5_in) //SHA1 static public string SHA1_Hash(string str_sha1_in)
hash 计算器 主用用于文本的MD5,crc32,SH1,sh256加密 解密
使用AES256加密技术实现tomcat7对连接池数据库密码加密解密,资源中包含加密小程序,小程序实现加密,tomcat中实现解密,方便客户自己修改数据库...支持多操作系统如:linux mac os 文件太多分成两部分请自行下载1和2
UnSHc, UnSHc如何解密 SHc *.sh.x 加密文件? UnSHcUnSHc - 如何解密 SHc *.sh.x 加密文件?请注意我不会给任何人解密任何文件。 GitHub上的问题只是讨论 Bug 和/或者工具"unshc"的改进。如果你认为你找到了一个 Bug...
使用方法:直接下载本资源,将打包之后的文件上传到Linux服务器上,进入bin目录执行启动命令:sh startup.sh -m standalone 访问:http://ip:8848/nacos/#/login 输入默认账号密码:nacos,nacos 建议登陆之后及时...
ubuntu tmux 自动执行shell脚本,可创建多个session,多个window。多个panes, 平铺所有的panes,对指定session下指定window的指定panes发送指定的多条命令,后台创建!...稍微修改可做成自己的自启动脚本,
linux下为程序创建启动和关闭的的sh文件,scrapyd为例.docx
安全的safesh使用SSH密钥存储和管理加密的机密。安装从下载safesh二进制文件。 运行chmod +x safesh使其可执行。 (可选)将其放在PATH的目录中。配置首次运行safesh时,它将询问您设置问题并在当前目录中创建config...
spring boot、springcloud项目一般为jar包形式运行,每次启动及关闭输命令很不爽,切且vm调优比较麻烦,编写shell脚本,将JVM调优参数及日常命令进行封装,操作简单,还不易出错,妙哉妙哉,此脚本已在我司正式使用...
linux服务器下jar包启动脚本:start.sh
前言:打包好的springboot项目,可以使用java -jar xxx.jar的方式启动。当出现多个springboot项目需要启动的时候,可以使用脚本启动的方式。这在springcloud项目的开发测试阶段尤为有用。以下展示启动脚本示例,过程...
linux下赋予该文件可执行权限 打开文件,配置好jar包路径和jar包名称后,可执行下面命令 $ ./autobot status $ ./autobot start $ ./autobot stop $ ./autobot restart