测试服务器:https://47.89.249.43:4433/git
(测试时,先将本机时间设置为2018年7月以前(我证书过时了),而后使用360国密浏览器访问。360国密浏览器会在TLS握手失败后才会发起GMSSL握手,因此访问较慢。出现访问不了的状况,请清除360国密浏览器全部缓存,重启浏览器后再访问)github
源码在 https://github.com/mrpre/atls 上能够得到算法
GM/T 没有单独规范 SSL协议的文件,而是在SSL VPN技术规范中定义了国密SSL协议。浏览器
规范号:GM/T 0024-2014缓存
这里主要讲的是国密SSL协议和标准的TLS协议之间的区别,根据这些区别,彻底能够实现国密SSL握手、通信,实现效果见文末。服务器
1:协议号dom
TLS协议号为0x0301 0x0302 0x0303,分别表示TLS1.0 1.1 1.2测试
而国密SSL版本号为0x0101,其参考了TLS1.1。加密
故本篇没有描述的握手、加密细节等所有参考TLS 1.1,本篇只罗列GM SSL 与 标准 TLS 之间的区别。spa
Client hello报文以下:
Wireshark是没法解析的该报文的(不知道新版本是否可以解析),若想解析,还须要手动把pcap报文中version对应的字段修改为通用的0x03xx,wireshark方能解析。
故该规范定义的SSL协议被称为 国密SSL 1.1。具体参考规范6.3.2.1。
2:加密算法
国密SSL定义了多个加密套件,见6.4.4.1.1
实际上,若加密各个阶段(非对称、对称、摘要)都替换成国密标准的,较主流的是以下2个
1:ECC_SM4_SM3
2:ECDHE_SM4_SM3
IBC并无研究过,这里再也不详细说明。
注意 ,ECDHE_SM4_SM3 必需要求双向认证。
ECC 对应的是标准的RSA,切勿被ECC迷惑,这个ECC并不和标准的椭圆曲线密钥交换算法相似,而是和RSA相似。服务器发送ECC公钥(在证书中)到客户端,客户端拿ECC公钥加密随机数给服务器(client key exchange)。
3:PRF算法
PRF算法和TLS 1.2相似,惟一区别:TLS1.2下,PRF算法为SHA256,而GM SSL的算法为SM3。
4:server key exhcnage
标准的server key exchange计算方式是
DH_sign(client_random + server_random + hash_in)
而国密SSL下server key exchange计算方式略有不一样
Sm2_sign(lient_random + server_random +hash_len + hash_in)
国密规范以下描述 server key exchange:
Case ECC:
Digitally-signed struct
{
Opaque client_random[32];
Opaque server_random[32];
Opaque ASN.1Cert<1, 2^24-1>;
}
Case ECDHE:
ServerECDHEParams params
Digitally-signed struct
{
Opaque client_random[32];
Opaque server_random[32];
ServerECDHEParams params
}
总结一下,
(1):
标准TLS server key exchange是椭圆曲线参数+对该报文的签名,签名时的hash是2个随机数加该报文自己。
(2):
国密SSL的ECC的server key exchange只是签名,因为自己不包含任何参数,故签名时的hash是2个随机数加上加密证书(注意国密规范描述证书时采用的尖括号的描述,即证书前须要加上长度信息表示)。具体签名算法使用的是sm2。
(3):
国密SSL的ECDHE证书和标准TLS就同样了,只是签名算法使用的是sm2。
Sm2签名须要一个ID,规范中建议为”1234567812345678”。实现上,都使用该值。
5:finished报文
标准TLS对finished使用标准的SHA一、SHA25六、SHA384等进行hash运算,国密SSL中,hash运算为smx。Hash运算完成后,就使用上面描述的prf算法进行计算。
6:certificate报文
国密规范定义发送证书时须要发送两个证书,签名证书和加密证书(双证书体系)。
与标准TLS报文格式同样,只是第一个证书是签名证书,第二个证书是加密证书。
我没有找到国密SSL规范定义怎么发送证书链的。
7:效果
使用360国密浏览器后,实现效果以下: