目录
数字签名
先说作用,作用是保证数据的完整性与不可篡改性,如果数据不完整或被修改了,用数据计算出来的签名就与发送过来的签名就会不一致。
数字签名基于非对称加密算法,非对称加密算法会有一个对应的公钥和私钥,特性是用公钥加密的数据只能用私钥解密,用私钥加密的数据只能用公钥解密。
其中私钥自己保管,公钥给通信的对端,当要发送数据给对端时,把要发送的数据计算一个校验和(sha或md5之类的),然后把该校验和使用私钥加密,得到的结果就是一个数字签名。把{数据,数字签名,公钥}一起发给对端,对端使用公钥对数字签名解密,再对数据计算校验和,两者的结果进行比较,一致的话就说明数据是完整且没被篡改过的。
数字证书
数字证书是为了证明接收到的公钥是可信任且是真正要与之通信的人,因为如上描述的{数据A,数字签名A,公钥A}通信数据是可以被拦截并修改为{数据B,数字签名B,公钥B}达到欺骗作用的。
比如小林要与小黄通信,小林通过数字证书认证机构(CA)购买数字证书,CA用自己的私钥对小林的{个人信息、公钥}加密后加上自己的公钥交付给小林一个数字证书。小林发给小黄的数据就从原来的{数据,数字签名,公钥}->{数据,数字签名,公钥,数字证书},小黄会从数字证书中取出CA的公钥(该公钥会去根证书列表中索引,如果不存在则提示该CA不受信任)并对数字证书中的加密内容进行解密,得到小林的公钥与个人信息,如果公钥与接收到的数据里的公钥相同且个人信息中包含小林的关键信息(小黄已经知道小林的关键信息的),这才说明该公钥是小林的。
SSL握手过程
1、Client Hello(客户端->服务端),客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等信息,相关信息如下:
• 支持的最高TLS协议版本version,从低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,当前基本不再使用低于 TLSv1 的版本;
• 客户端支持的加密套件 cipher suites 列表, 每个加密套件对应前面 TLS 原理中的四个功能的组合:密钥交换算法 KeyExchange(密钥协商)、验证算法 Au (身份验证)、对称加密算法(握手成功后数据通信加密使用的算法)和信息摘要 Mac(完整性校验),如TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,ECDHE为密钥协商的方法,RSA为非对称加密算法,与公私钥配合验证数据,AES_256_GCM为对称加密算法,SHA384为信息摘要算法;
• 支持的压缩算法 compression methods 列表,用于后续的信息压缩传输;
• 随机数 random_C,用于后续的密钥enc_key的生成
2、Server Hello(服务端->客户端),服务端返回协商的信息结果,包括选择使用的协议版本 version,选择的加密套件 cipher suite,选择的压缩算法 compression method、随机数 random_S 等,其中random_S用于后续的密钥enc_key的生成
3、Certificate(服务端->客户端),服务端返回证书,包含公钥与身份验证的信息
4、Server Key Exchange(服务端->客户端),ECDHE类的才有该消息,作用是 server certificate 没有携带足够的信息时,发送给客户端以计算 PreMaster Secret,如基于 DH 的证书,公钥不被证书中包含,需要单独发送
5、Server Hello Done(服务端->客户端),通知客户端Server Hello消息结束,需要该消息是因为客户端可能需要在Server Hello结束后继续发送其他消息
6、Client Key Exchange(客户端->服务端),客户端生成PreMaster Secret(RSA类的)或EC Diffie-Hellman Client Params(ECDHC类的),统称为CKEY吧,使用服务端的公钥加密后发送给服务端,双方使用{random_C、random_S、CKEY}计算得到后续通信的enc_key
7、Change Cipher Spec(客户端->服务端),通知服务端后续通信数据采用前面协商好的加密算法和enc_key加解密
8、Encrypted Handshake Message(客户端->服务端),把该消息之前的所有消息集合起来计算一个消息摘要,发送给服务端验证之前收到的数据是否正确,服务端收到该消息并验证通过则握手完成
9、Change Cipher Spec(服务端->客户端),通知客户端后续通信数据采用前面协商好的加密算法和enc_key加解密
10、Encrypted Handshake Message(服务端->客户端),把该消息之前的所有消息集合起来计算一个消息摘要,发送给客户端验证之前收到的数据是否正确,客户端收到该消息并验证通过则握手完成
重点:SSL握手的终极目的是为了得到一个对称加密算法和key用于之后的数据通信加密,且客户端与服务端能够在握手过程中双向认证
go跨平台优势
发现了一个go在跨平台上得天独厚的优势,go是静态链接的,包括了C库,所以它不像我们C/C++得根据系统的C库类型是glibc、musl、uclibc编译不同的版本,比如x86_64架构的go只要编译一个就能在这几个类型的系统上跑。
我自己静态链接C库,但链接的时候警告有一些函数是依赖于runtime的,虽然编译过去了,但实际运行那些函数会失败;查了资料,因为go自己实现了runtime,所以它能够正常与不同C库的系统打交道