gmsm/docs/pkcs7.md
2024-06-20 11:49:10 +08:00

5.1 KiB
Raw Blame History

PKCS7应用指南

本项目实现 PKCS#7/加密消息语法的子集rfc2315、rfc5652以及相应国密支持《GB/T 35275-2017 信息安全技术 SM2密码算法加密签名消息语法规范》。这是 mozilla-services/pkcs7 的一个分支,目前mozilla-services/pkcs7已经是弃用状态,代码仓库也已经进入存档、只读状态。

支持的功能

数字信封数据Enveloped Data

数字信封数据,使用对称加密算法加密数据,使用非对称加密加密数据密钥。支持的对称加密算法(以及模式)有

  • AES128-CBC
  • AES192-CBC
  • AES256-CBC
  • AES128-GCM
  • AES192-GCM
  • AES256-GCM
  • DES-CBC
  • 3DES-CBC
  • SM4-CBC
  • SM4-GCM

支持的非对称加密算法为:

  • RSAPKCS1v15目前尚不支持RSAOAEP
  • SM2

主要方法

是否国密是指OID也使用国密体系

是否国密 加密 解密(先调用Parse
Encrypt Decrypt
EncryptUsingPSK DecryptUsingPSK
EncryptSM Decrypt
EncryptCFCA DecryptCFCA
EncryptSMUsingPSK DecryptUsingPSK

关于EncryptSM / EncryptCFCA的区别,请参考CFCA互操作性指南
带PSKPre-shared key后缀的方法其对称加密密钥由调用者提供而非随机生成。

加密数据Encrypted Data

加密:对应本项目的pkcs7.EncryptUsingPSKpkcs7.EncryptSMUsingPSK方法。
解密:对应本项目的pkcs7.DecryptUsingPSK方法(当然要先调用pkcs7.Parse)。

签名数据Signed Data

签名数据,使用证书对应的私钥进行签名,理论上支持多个签名者,但通常使用场景都是单签。和数字信封数据类似,也分国密和非国密。

创建签名数据

是否国密是指OID也使用国密体系

是否国密 方法 默认签名算法
NewSignedData SHA1
NewSMSignedData SM3

可选步骤:调用SetDigestAlgorithm设置想要的签名算法,通常国密不需要修改。
接着调用AddSignerAddSignerChain方法,进行签名;可以通过SignerInfoConfig.SkipCertificates指定忽略证书项(最终签名数据中不包含证书项);
如果进行Detach签名则调用Detach方法;
最后调用Finish方法,序列化输出结果。

验证签名

而验证的话,流程如下:

  1. 调用Parse方法;
  2. 如果是Detach签名数据则手动设置原始数据参考testSign方法);
  3. 如果签名数据中不包含证书项,则手动设置验签证书(参考TestSkipCertificates
  4. 调用VerifyVerifyWithChain方法。

特殊方法

DegenerateCertificate退化成签名数据中只包含证书目前没有使用SM2 OID的方法如果需要可以请求添加。可以参考TestDegenerateCertificateTestParseSM2CertificateChain

签名及数字信封数据Signed and Enveloped Data

签名和数字信封数据使用场景较少有些实现用它来传输私钥譬如www.gmcert.org。具体请参考sign_enveloped_test.go

The "signed and enveloped data" content type is a part of the Cryptographic Message Syntax (CMS), which is used in various Internet Standards. However, it's not recommended for use due to several reasons:

  1. Complexity: The "signed and enveloped data" content type combines two operations - signing and enveloping (encryption). This increases the complexity of the implementation and can lead to potential security vulnerabilities if not handled correctly.

  2. Order of Operations: The "signed and enveloped data" content type first signs the data and then encrypts it. This means that to verify the signature, the data must first be decrypted. This could potentially expose sensitive data to unauthorized parties before the signature is verified.

  3. Lack of Flexibility: Combining signing and enveloping into a single operation reduces flexibility. It's often more useful to be able to perform these operations separately, as it allows for more varied use cases.

Instead of using the "signed and enveloped data" content type, it's generally recommended to use separate "signed data" and "enveloped data" content types. This allows the operations to be performed in the order that best suits the application's needs, and also simplifies the implementation.

加密签名流程

  1. 调用NewSignedAndEnvelopedData或者NewSMSignedAndEnvelopedData创建SignedAndEnvelopedData数据结构,此过程包含了数据加密过程;
  2. 调用AddSignerAddSignerChain方法,进行签名;
  3. 调用AddRecipient方法用Recipient的公钥加密数据密钥
  4. 最后调用Finish方法,序列化输出结果。

解密验签流程

  1. 调用Parse方法;
  2. 调用DecryptAndVerify或者DecryptAndVerifyOnlyOne进行解密和验签。