1 简介

铜锁/Tongsuo是一个提供现代密码学算法和安全通信协议的开源基础密码库,为存储、网络、密钥管理、隐私计算等诸多业务场景提供底层的密码学基础能力,实现数据在传输、使用、存储等过程中的私密性、完整性和可认证性,为数据生命周期中的隐私和安全提供保护能力。

铜锁应用场景:

  1. 存储加密
  2. 网络传输:支持 TLS 、QUIC 、RFC8998、TLCP安全传输协议
  3. 密码合规
  4. 密钥管理
  5. 隐私计算:支持同态加密、零知识证明等算法

铜锁与OpenSSL对比:

2 国密算法介绍

国密常见的算法有 SM2 、SM3、SM4、SM9,具体分类如下:

  1. 对称加密算法
    • SM1算法:对称加密算法,用于替代国际标准的DES算法。
    • SM4算法:对称分组密码算法,被用于替代国际标准的AES算法。
  2. 非对称加密算法
    • SM2算法:非对称加密算法,用于数字签名、密钥协商等。
    • SM9算法:基于椭圆曲线密码体制的身份认证密码学算法。
  3. 哈希算法
    • SM3算法:密码哈希函数,用于替代MD5、SHA-1等哈希算法。

2.1 SM4 算法

2.1.1 简介

SM4是对称算法,与国际上的算法 如:AES 对应,可以对数据进行对称加密,主要特点如下:

  1. 密钥长度128比特
  2. 分组长度128比特
  3. 轮函数迭代32次
  4. 解密轮密密钥与加密轮密钥顺序相反
  5. 使用非平衡Feistel网络结构

2.1.2 SM4 轮函数

SM4 的轮函数对输入进行处理,按SM4算法特点,会迭代执行32次,具体逻辑如下:

2.1.3 SM4 padding

SM4的密钥长度为128 比特,也就是16字节,如果输入的待加密的数据不是16字节的整数倍,就需要进行填充。

铜锁是使用默认的 PKCS7 的填充方式:

PKCS7 的填充逻辑为,把最后一块明文与16字节对比,把缺少的字节都设置为缺少的字节值。如上实例 “hello world”,后边缺少5个字节,都设置为了 16进制的 05。在解密后可以知道后边有5个字节是填充数据。

上边第二个实例,明文长度为16字节,但是 后边还会继续填充 16字节,是为了避免造成歧义。

如果明文刚好长度为16字节,并且最后的两个字节为 02 02 ,此时就会造成歧义,无法确定最后的两个字节是填充还是真实的明文数据。

2.1.4 SM4 链接模式

SM4 与其他的国际上对称加密算法一样,支持不同的分组模式,如 ECB 和 CBC。

ECB模式:

  • 分组独立加解密,利于并行
  • 相同明文对应相同密文
  • 难以抵挡统计分析攻击和分组重放攻击
  • 不安全,不建议使用

CBC模式:

  • 上一次的密文分组参与下一次的加密或解密
  • 需要初始化向量(IV)
  • 加密串行,解密可以并行

![[Pasted image 20231212112953.png]]

2.2 SM3 算法

SM3算法:密码哈希函数,用于替代MD5、SHA-1等哈希算法。
输入消息:小于2^64比特
输出杂凑值:256比特
应用场景:用于完整性校验、身份认证、数字签名、消息认证码、密钥推导、随机数生成器等。

2.3 SM2 算法

2.3.1 简介

SM2算法主要基于椭圆曲线密码学,实现非对称加密。椭圆曲线应用在密码学,主要依赖椭圆曲线的离散对数问题困难性。

2.3.2 SM2签名算法

SM2算法可以应用在数字签名中。使用 私钥签名,公钥验签,SM2的签名算法是指 SM2-With-SM3(使用SM2算法签名,然后使用SM3算法对签名数据计算一个摘要)。

签名算法逻辑如下:

2.3.3 SM2 密钥交换

可以基于SM2实现密钥交换,公钥加密,私钥解密。
输入:消息M,长度为len,用户B的密钥对包括私钥dB 和 PB = [dB]G

SM2公钥加密步骤如下:

最后输出 密文 C。

SM2 私钥解密,参考 GB/T 32918.4-2016 SM2椭圆曲线公钥密码算法 第4部分:公钥加密算法

SM2密钥交换算法步骤:

3 国密证书

3.1 国际证书与国密证书对比

国际证书与国密证书对比,国密证书也可以 称为 SM(ShangMi 商密)。

3.2 证书生命周期

  1. CSR (certificate signing request) ,证书签发请求
  2. CA(certificate authority),证书颁发机构;
  3. CRL (certificate revocation list) ,证书吊销列表
  4. OCSP (online certificate status protocol) ,在线证书状态协议

信赖方在访问Web服务器时请求证书,对证书进行验证,同时检测证书的状态,可以查看证书吊销列表或者发送OCSP请求,判断证书是否过期等。

由于获取CRL(证书吊销列表)需要传输大量数据,性能较差,可以发送 OCSP请求,指定要查询的证书状态。

3.3 证书信息

国密的证书信息格式与国际证书类似,主要有如下信息字段:

  1. 版本:目前以V3为主
  2. 序列号:每个CA证书唯一标识
  3. 签名算法:SM2证书为 SM2-with-SM3
  4. 颁发者:颁发者(issuer)的可分辨名称,包括国家、组织和组织单位等。
  5. 有效期:开始时间和结束时间
  6. 使用者:使用者(subject)的可分辨名称
  7. 使用者公钥信息:公钥算法ID和公钥
  8. 证书签名值
  • 证书的扩展信息
  1. 使用者可选名称(Subject Alternative Name):支持设置多个DNS名称、IP地址等,代替使用者字段中的通用名(Common name)
  2. 基础约束(BasicConstraints):证书是否为CA证书;
  3. 密钥用法(Key Usage):密钥使用场景,例如数字签名、证书签名、CRL签名、密钥加密、数据加密、密钥协商、抗抵赖等
  4. 扩展密钥用法(Extended Key Usage):更加灵活地支持和限制公钥的使用场景,比如客户端身份验证、服务端身份验证
  5. 证书策略(Certificate Policies):证书签发的法律条款;
  6. CRL分发点(CRL Distribution Points):通过访问这个地址获取证书吊销列表
  7. 颁发机构信息访问(AuthorityInfo Access):包括OCSP响应程序地址,CA证书地址;
  8. 使用者密钥标识符(Subject Key ID):该证书的唯一标识符
  9. 授权密钥标识符(Authority Key ID):签发该证书的CA证书的唯一标识符
  • 证书类型
  1. DV,域名验证,CA验证域名的所有权
  2. OV,组织验证,CA验证域名的所有权和企业的真实身份信息,比如组织机构代码、经办人身份证号等
  3. EV,增强验证,更加严格的验证身份和真实性,可能需要提交律师函、律师证等信息;

示例:

4 国密传输协议

4.1 握手协议

关于国密规范有两个:

  1. 行标:GM/T 0024-2014 SSL VPN技术规范
  2. 国标:GB/T 38636-2020 传输层密码协议(TLCP)

以上两个规范的差异主要是TLCP会比 SSL VPN多了几个密码套件。

下边以TLCP为例:

TLCP 建立连接,主要包括记录层协议 和 握手协议簇。
![[Pasted image 20231212145558.png]]

4.2 TLCP握手

TLCP 握手过程 与 TLS 握手类似,只是因为国密是双证书,一个签名证书,一个加密证书,在握手时服务器响应的 Certificate 种包含两个证书。

具体解释下以上的握手过程:

  1. 客户端发送 ClientHello 数据包,开始请求建立连接,核心参数包括:客户端生成的随机数(client_random)、客户端支持的TLCP版本号(目前就是 TLCPv1.1,是十六进制是 0x0101)、客户端支持的密码套件等
  2. 服务端响应 ServerHello,告诉客户端选定的密码套件(cipher_suites)、服务端生成的随机数(server_random)、服务端的TLCP版本号
  3. 服务端响应 Certificate,发送服务端的签名证书和加密证书给客户端,也可能包括证书链,客户端需要验证证书,
  4. 服务端响应 ServerKeyExchange,服务端使用签名证书的私钥 以上协商过程的数据(client_random + server_random + 加密证书)做一个签名,发送给客户端,客户端可以使用签名证书的公钥验证签名,方式握手数据被篡改
  5. 服务端响应 ServerHelloDone,标识服务端数据发送完
  6. 客户端发送 ClientKeyExchange,客户端生成预主密钥pre_master_secret,使用服务端的加密证书的公钥进行加密发送给服务端,此时客户端可以通过 pre_master_secret、client_randon、server_random 推导主密钥(master_secret),通过主密钥推导工作密钥(真正用于解密传输数据的密钥)
  7. 服务端接收到 第6步 的客户端请求后,使用加密证书的私钥解密预主密钥,同样,通过 pre_master_secret、client_random、server_random 推导主密钥,通过主密钥推导出工作密钥(真正用于解密传输数据的密钥),这里计算出来的工作密钥与第6步中客户端计算出来的应该一样。
  8. 客户端发送 ChangeCipherSpec,使用计算出来的工作密钥加密 协商过程的数据,发送给服务端。
  9. 客户端发送 Finished,标识握手结束
  10. 服务端响应 ChangeCipherSpec,服务端对第8步客户端发送的数据使用计算出来的工作密钥进行解密,加密数据中最后也有摘要信息,进行摘要的验证,确定数据解密成功
  11. 服务端响应 Finished,标识握手结束,后边进行加密通信

握手结构体定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct {
HandshakeType msg_type;
uint24 length;
select (msg_type){
case client_hello: ClientHello:
case server_hello: ServerHello;
case certificate: Certificate:
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
)body;
)Handshake;

4.3 TLCP 密码套件

4.4 TLCP 密钥计算

工作密钥就是在传输数据过程中对数据加密的密钥