openssl 密码套件相关内容(OID|密码套件)

本文介绍了SSL通信中如何通过OID识别和使用国密算法,详细阐述了OID的分层树形结构及其编码规则。同时,讨论了密码套件在TLS握手过程中的作用,强调了协商过程和服务器选择加密套件的重要性。GmSSL实现了部分国密密码套件,并提供了查看支持套件的命令。在实际操作中,通过设置加密套件选择符号来影响协商过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考链接

OID

  • OID是由ISO/IEC、ITU-T国际标准化组织上世纪80年代联合提出的标识机制,其野心很大,为任何类型的对象(包括实体对象、虚拟对象和组合对象)进行全球唯一命名。
  • 通过唯一的编码,我们就可以识别出对象。但要为所有对象进行唯一命名,其难度和工作量都很大,所以它采用了分层树形结构。
  • OID对应于“OID树”或层次结构中的一个节点,该节点是使用ITU的OID标准X.660正式定义的。
  • 树的根包含以下三个起点:0:ITU-T1:ISO2:ITU-T/ISO联合发布
  • 树中的每个节点都由一系列由句点分隔的整数表示。比如,表示英特尔公司的OID如下所示:1.3.6.1.4.1.343
  • 1               ISO1.3             识别组织1.3.6           美国国防部1.3.6.1         互联网1.3.6.1.4       私人1.3.6.1.4.1     IANA企业编号  1.3.6.1.4.1.343 因特尔公司
  • 这里采用分而治之的策略,解决编码重复问题。树中的每个节点均由分配机构控制,该机构可以在该节点下定义子节点,并为子节点委托分配机构。在上面的例子中,根节点“1”下的节点号由ISO分配,“1.3.6”下的节点由美国国防部分配,“1.3.6.1.4.1”下的节点由IANA分配,“1.3.6.1.4.1.343”下的节点由英特尔公司分配,依此类推。只要有需求,可以一直往下分配下去,也解决了编码不够的问题。

  • 在实际应用中,ISO/IEC国际标准化机构维护顶层OID标签,各个国家负责该国家分支下的OID分配、注册和解析等工作,实现自我管理和维护。相应的,针对国密,国家密码局也定义了各类对象的标识符:
  • GMT 0006-2012 密码应用标识规范.pdf GM-Standards/GMT 0006-2012 密码应用标识规范.pdf at master · guanzhi/GM-Standards · GitHub

 

  • 像"1.2.156.10197.1.100"这种字符串,人读起来比较直观,但对于计算机对字符串处理的效率非常低,所以在程序代码中,对OID又进行了一次编码。
  • 通过 objects.pl 脚本,生成 obj_data.h文件,这个才是在代码中使用到的OID编码。 boringssl也类似,不过其采用了 go 语言编写的转换脚本。
  • 在GmSSL源码中,原始的OIDs定义在crypto/objects/objects.txt文件中,在文件的尾部,我们可以看到国密的相关定义:

 国密相关定义

sm-scheme 102 1		: SM1-ECB		: sm1-ecb
sm-scheme 102 2		: SM1-CBC		: sm1-cbc
!Cname sm1-ofb128
sm-scheme 102 3		: SM1-OFB		: sm1-ofb
!Cname sm1-cfb128
sm-scheme 102 4		: SM1-CFB		: sm1-cfb
sm-scheme 102 5		: SM1-CFB1		: sm1-cfb1
sm-scheme 102 6		: SM1-CFB8		: sm1-cfb8


# SM2 OIDs
sm-scheme 301		: sm2p256v1
sm-scheme 301 1		: sm2sign
sm-scheme 301 2		: sm2exchange
sm-scheme 301 3		: sm2encrypt

sm-scheme 501		: SM2Sign-with-SM3	: sm2sign-with-sm3
sm-scheme 502		: SM2Sign-with-SHA1 	: sm2sign-with-sha1
sm-scheme 503		: SM2Sign-with-SHA256	: sm2sign-with-sha256
sm-scheme 504		: SM2Sign-with-SHA511	: sm2sign-with-sha512
sm-scheme 505		: SM2Sign-with-SHA224	: sm2sign-with-sha224
sm-scheme 506		: SM2Sign-with-SHA384	: sm2sign-with-sha384
sm-scheme 507		: SM2Sign-with-RMD160	: sm2sign-with-rmd160
sm-scheme 520		: SM2Sign-with-Whirlpool : sm2sign-with-whirlpool
sm-scheme 521		: SM2Sign-with-Blake2b512 : sm2sign-with-blake2b512
sm-scheme 522		: SM2Sign-with-Blake2s256 : sm2sign-with-blake2s256

sm2encrypt 1		: sm2encrypt-recommendedParameters
sm2encrypt 2		: sm2encrypt-specifiedParameters
sm2encrypt 2 1		: sm2encrypt-with-sm3
sm2encrypt 2 2		: sm2encrypt-with-sha1
sm2encrypt 2 3		: sm2encrypt-with-sha224
sm2encrypt 2 4		: sm2encrypt-with-sha256
sm2encrypt 2 5		: sm2encrypt-with-sha384
sm2encrypt 2 6		: sm2encrypt-with-sha512
sm2encrypt 2 7		: sm2encrypt-with-rmd160
sm2encrypt 2 8		: sm2encrypt-with-whirlpool
sm2encrypt 2 9		: sm2encrypt-with-blake2b512
sm2encrypt 2 10		: sm2encrypt-with-blake2s256
sm2encrypt 2 11		: sm2encrypt-with-md5

# SM3
sm-scheme 401		: SM3			: sm3
sm-scheme 401 2		: HMAC-SM3		: hmac-sm3

# SM4
sm-scheme 104 1		: SMS4-ECB		: sms4-ecb
sm-scheme 104 2		: SMS4-CBC		: sms4-cbc
!Cname sms4-ofb128
sm-scheme 104 3		: SMS4-OFB		: sms4-ofb
!Cname sms4-cfb128
sm-scheme 104 4		: SMS4-CFB		: sms4-cfb
sm-scheme 104 5		: SMS4-CFB1		: sms4-cfb1
sm-scheme 104 6		: SMS4-CFB8		: sms4-cfb8
sm-scheme 104 7		: SMS4-CTR		: sms4-ctr
sm-scheme 104 8		: SMS4-GCM		: sms4-gcm
sm-scheme 104 9		: SMS4-CCM		: sms4-ccm
sm-scheme 104 10	: SMS4-XTS		: sms4-xts
sm-scheme 104 11	: SMS4-WRAP		: sms4-wrap
sm-scheme 104 12	: SMS4-WRAP-PAD		: sms4-wrap-pad
sm-scheme 104 100	: SMS4-OCB		: sms4-ocb

# SM5/6/7/8
sm-scheme 201		: SM5			: sm5
sm-scheme 101 1		: SM6-ECB		: sm6-ecb
sm-scheme 101 2		: SM6-CBC		: sm6-cbc
!Cname sm6-ofb128
sm-scheme 101 3		: SM6-OFB		: sm6-ofb
!Cname sm6-cfb128
sm-scheme 101 4		: SM6-CFB		: sm6-cfb
!Alias sm7 sm-scheme 105
!Alias sm8 sm-scheme 106

# SM9
sm-scheme 302		: id-sm9PublicKey
sm-scheme 302 1		: sm9sign
sm-scheme 302 2		: sm9keyagreement
sm-scheme 302 3		: sm9encrypt
sm-scheme 302 4		: sm9hash1
sm-scheme 303 7		: sm9hash2
sm-scheme 302 5		: sm9kdf
sm-scheme 302 6		: id-sm9MasterSecret
sm-scheme 302 6	1 	: sm9bn256v1
sm9sign 1		: sm9sign-with-sm3
sm9sign 2		: sm9sign-with-sha256
sm9encrypt 1		: sm9encrypt-with-sm3-xor
sm9encrypt 2		: sm9encrypt-with-sm3-sms4-cbc
sm9encrypt 3		: sm9encrypt-with-sm3-sms4-ctr
sm9hash1 1		: sm9hash1-with-sm3
sm9hash1 2		: sm9hash1-with-sha256
sm9hash2 1		: sm9hash2-with-sm3
sm9hash2 2		: sm9hash2-with-sha256
sm9kdf 1		: sm9kdf-with-sm3
sm9kdf 2		: sm9kdf-with-sha256

密码套件

  • 仅仅定义了OID还不够,因为国密并不是一个单一的标准,包含了很多加密、解密、哈希等算法,可以形成很多种组合,不能简单假定对方采用了国密就可以建立通信。
  • 在SSL通信开始,双方就需要进行协商,采用何种算法进行通信。这就引出了密码套件(CipherSuite)的概念。
  • 密码套件是一系列密码学算法的组合,主要包含多个密码学算法:
    • 密钥交换算法:用于握手过程中建立信道,一般采用非对称加密算法
    • 数据加密算法:用于信道建立之后的加密传输数据,一般采用对称加密算法
    • 消息验证算法:用于验证消息的完整性,包括整个握手流程的完整性(例如TLS握手的最后一步就是一个对已有的握手消息的全盘哈希计算的过程)
  • 密码套件的构成如下图所示:

  • /home/chy-cpabe/Downloads/GmSSL-master/README.md  文件内部包含了国密算法套件的定义 

  • 代码可以参考 gmtls.h 文件,也可以使用GMSSL的命令查看所支持的密码套件: openssl ciphers -V | column -t
  • 如果使用gmssl,将openssl替换成gmssl即可,如果未配置全局路径,需要到编译后生成的可执行脚本处执行上述命令 

 

  • 第一列:数值代表密码套件的编号,每个密码套件的编号由IANA定义。
  • 第二列:代表密码套件的名称,虽然密码套件编号是一致的,不同的TLS/SSL协议实现其使用的名称可能是不一样的。
  • 第三列:表示该密码套件适用于哪个TLS/SSL版本的协议。
  • 第四列:表示密钥协商算法。
  • 第五列:表示身份验证算法。
  • 第六列:表示加密算法、加密模式、密钥长度。
  • 第七列:表示HMAC算法。其中AEAD表示采用的是AEAD加密模式(比如AES128-GCM),无须HMAC算法。

操作流程

  • 一个密码学套件是完成整个TLS握手的关键。在TLS握手的时候ClientHello里面携带了客户端支持的密码学套件列表,ServerHello中携带了Server根据Client提供的密码学套件列表中选择的本地也支持的密码学套件。
  • 也就是说选择使用什么密码学套件的选择权在Server的手里,这句话感觉有问题,客户端先选择密码学套件列表,看服务器是否支持,或者服务器考虑到算法的安全性会禁用不安全的密码学套件  我的这句话有问题,借此提醒

注意事项

  • 值得注意的是,这里的编码又没有采用OID,这也是开发过程中需要注意的,不同的地方使用了不同标准规范,需要在开发中翻阅相应的协议和规范。
  • 可以看出,GmSSL并没有实现所有的国密的密码套件,但同时又扩充了几个标准未定义的密码套件,比如ECDHE-SM2-WITH-SMS4-GCM-SM3、ECDHE-SM2-WITH-SMS4-SM3等。这就体现出协商的重要性了,对双方所支持的密码套件取一个交集,从中选择一个。如果不存在交集,协商也就不成功。注意,协商过程中服务器端可能会禁用一些不太安全的密码套件(比如历史遗留的一些现今已不太安全的算法),这时即使双方都支持,也可能协商不成功。
  • 我们可以测试服务器是否支持某个特定的密码套件:

 代码编写

  • Openssl定义了4中选择符号:“+”,“-”,“!”,“@”。其中,“+”表示取交集;“-”表示临时删除一个算法;“!”表示永久删除一个算法;“@“表示了排序方法。
  • 多个描述之间可以用“:”或“,”或空格或“;”来分开。选择加密套件的时候按照从左到的右顺序构成双向链表,存放与内存中。
ALL:!DH:RC4+RSA:+SSLv2:@STRENGTH
  • 表示的意义是:首先选择所有的加密套件,然后在得到的双向链表之中去掉密钥交换采用DH的加密套件;加入包含RC4对称加密算法与RSA身份认证算法的交集加密套件;再将支持老版本SSLv2的加密套件放在尾部;最后,@STRENGTH表示将得到的结果按照安全强度进行排序。
  • SSL建立链接之前,客户端和服务器端用openssl函数来设置自己支持的加密套件。主要的函数有:
int SSL_set_cipher_list(SSL *s, const char *str);
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str);
  • 比如只设置一种加密套件:
int ret=SSL_set_cipher_list(ssl,"RC4-MD5"); 
  • 如果服务端只设置了一种加密套件,那么客户端要么接受要么返回错误。
  • 加密套件的选择是由服务端做出的。客户端没有权利指定其他加密套件。
### Wireshark 中解析国密算法 SM 系列加密通信 #### 配置环境准备 为了能够在 Wireshark 中查看并解析基于国密标准 (GM/T) 的 SM 系列加密通信,需先安装支持这些密码套件的库文件以及配置好相应的解密设置。通常情况下,这涉及到 OpenSSL 或 GnuTLS 库的支持版本更新至能够识别中国国家商用密码算法[^1]。 #### 启用 SSL/TLS 解密功能 对于 HTTPS 流量或者其他采用 TLS 协议传输的数据包捕获,在偏好设置中的 Protocols -> TLS 节点下勾选 "Enable decryption" 并指定会话密钥日志文件路径(即 `SSLKEYLOGFILE`),该文件记录着客户端随机数、服务器随机数及预主秘钥等必要参数用于后续还原明文数据流[^2]。 #### 添加自定义 EKU OID 和 Cipher Suite ID 映射表项 由于部分国产化应用可能使用特定的企业单位对象标识符(Enterprise Key Usage OIDs),因此还需要向 Wireshark 注册额外的安全机制描述以便更精确地匹配到对应的加/解密操作过程;同样地,针对某些非公开发布的 cipher suite IDs 可能也需要手动维护一份映射关系列表来辅助工具理解未知类型的协商结果[^3]。 #### 使用插件扩展解析能力 如果内置的功能不足以满足需求,则可以考虑开发或寻找第三方提供的 Lua脚本形式的插件来进行增强处理。这类附加组件往往聚焦于解决某一类特殊场景下的报文结构拆分难题,并且允许用户通过简单的函数调用来实现定制化的展示效果[^4]。 ```lua -- 示例:创建一个新的 dissector 来处理 GM/T 0028-2014 定义的消息格式 local sm_dissector = Proto("sm", "State Cryptography Algorithm") function sm_dissector.dissect(buffer, pinfo, tree) local subtree = tree:add(sm_dissector, buffer(), "SM Protocol Data") -- 假设这里存在一个已知长度字段作为入口... end register_postdissector(sm_dissector) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值