既然是要构造国密规范的消息语法数据类型,那当然要用到gmssl库咯。(GmSSL项目是OpenSSL项目的分支,并与OpenSSL保持接口兼容。因此GmSSL可以替代应用中的OpenSSL组件,并使应用自动具备基于国密的安全能力。)
1、引出问题
我们知道openssl中是已实现了RFC规范中的各种类型数据的定义。这些定义在gmssl中同样存在。从之前的文章我们了解到国密规范的消息语法类型与RFC规范中的基本一致(主要是某些字段填入的数据存在差异),因此我们可以使用gmssl中的pkcs#7模块的相关封装接口来实现数据的封装。
虽然可以使用但是若直接调用pkcs#7模块去做的话,最后出来的数据肯定不符合国密规范,因为OID不对呀。gmssl库不支持GM/T0010规范中定义的OID。 那怎么办捏?
也许有童鞋会说“那把OID改成国密规范中的OID呀”。 是的,可以改,因为OID是类型标识符,并不参与实际的密码运算。但是改完后就会发现DER编码(i2d_PKCS7(...))会失败。[○・`Д´・ ○]
查看gmssl源码,可知pkcs7结构定义如下:
其内部有一个union(包含消息语法规范中的各类型),通过ASN1_OBJECT *type来指明当前内容是哪种类型。在进行DER编解码时会根据type来选择对应的数据结构进行序列化。而如果type被修改为gmssl中不识别的值(例如国密规范的OID对应的值),就无法匹配到合适的类型,也就无法进行DER编解码。
2、解决方案
目前解决方案有二(就小编目前的认知┐( ̄ヘ ̄)┌)。
方案一:修改gmssl源码,添加对GM/T0010规范中OID的支持。(难度较高)
方案二:自定义asn1结构,然后通过gmssl的ASN库对其进行编码处理。
下面简单介绍下方案二思路:(具体代码就不太好帖出来了,因为是公司同事的代码,你懂的ㄟ( ▔, ▔ )ㄏ )
该方案主要是运用gmssl库中的ANS.1(是一套灵活的标记语言)允许定义多种数据类型的特性来实现。也就是不用gmssl中已有的pkcs7结构,而是自定义结构(包含类型type以及消息数据类型data或PKCS7_ENVELOP或PKCS7_SIGN_ENVELPE等类型)。
a、用ASN.1语法自定义内部数据结构,并通过DECLARE_ASN1_FUNCTIONS声明函数;
b、然后通过ASN.1宏实现自定义结构的最基本的四个函数(new, free, i2d, d2i);
更详细的ASN.1库DER编解码步骤以及示例请参考https://www.cnblogs.com/aixiaoxiaoyu/articles/8304070.html
------------*✧⁺˚⁺ପ(๑・ω・)੭ु⁾⁾ 好好学习天天向上------------
后续文章将针对国密规范中的每一种类型的消息语法数据具体如何构造进行讲解,敬请期待~