pkcs7: update comments and document

This commit is contained in:
Sun Yimin 2025-01-16 10:59:30 +08:00 committed by GitHub
parent 057ddb5bcb
commit cf6e203d06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 31 deletions

View File

@ -40,18 +40,25 @@
### 签名数据Signed Data
签名数据,使用证书对应的私钥进行签名,理论上支持多个签名者,但通常使用场景都是单签。和数字信封数据类似,也分国密和非国密。
#### 创建签名数据
#### 签名流程
1. 创建SignedData
是否国密是指OID也使用国密体系
| 是否国密 | 方法 | 默认签名算法 |
| :--- | :--- | :--- |
| 否 | ```NewSignedData``` | SHA1 |
| 是 | ```NewSMSignedData``` | SM3 |
| 是否国密 | 数据是否是哈希值 | 方法 | 默认签名算法 |
| :--- | :--- | :--- | :--- |
| 否 | 否 | ```NewSignedData``` | SHA1 |
| 否 | 是 | ```NewSignedDataWithDigest``` | SHA1 |
| 是 | 否 | ```NewSMSignedData``` | SM3 |
| 是 | 是 | ```NewSMSignedDataWithDigest``` | SM3 |
可选步骤:调用```SetDigestAlgorithm```设置想要的签名算法,通常国密不需要修改。
接着调用```AddSigner```或```AddSignerChain```方法,进行签名;可以通过```SignerInfoConfig.SkipCertificates```指定忽略证书项(最终签名数据中不包含证书项);
如果进行Detach签名则调用```Detach```方法;
最后调用```Finish```方法,序列化输出结果。
2. 可选步骤:调用```SetDigestAlgorithm```设置想要的签名算法,通常国密**不需要**修改。
3. 接着调用```AddSigner```或```AddSignerChain```方法,进行签名;可以通过```SignerInfoConfig.SkipCertificates```指定忽略证书项(最终签名数据中不包含证书项);
4. 如果进行Detach签名则调用```Detach```方法;
5. 最后调用```Finish```方法,序列化输出结果。
**注意**
1. 如果是直接对哈希值签名一定是Detach签名。
2. 国密签名如果要传入哈希值在有Attribute的情况下则哈希值只是标准的SM3哈希值否则必须是符合SM2签名标准的哈希值含SM2公钥信息
#### Detach签名
就是外部签名,**被签名数据**不包含在SignedData中也就是其ContentInfo.Content为空
@ -86,7 +93,7 @@ if err := p7.VerifyWithChain(truststore); err != nil {
1. 调用```Parse```方法;
2. 如果是Detach签名数据则手动设置原始数据参考```testSign```方法);
3. 如果签名数据中不包含证书项,则手动设置验签证书(参考```TestSkipCertificates```
4. 调用```Verify```或```VerifyWithChain```方法。
4. 如果Content是原始数据调用```Verify```或```VerifyWithChain```方法如果Content是哈希值调用```VerifyAsDigest```或```VerifyAsDigestWithChain```方法。
#### 特殊方法
```DegenerateCertificate```退化成签名数据中只包含证书目前没有使用SM2 OID的方法如果需要可以请求添加。可以参考```TestDegenerateCertificate```和```TestParseSM2CertificateChain```。

View File

@ -48,9 +48,9 @@ func NewSignedData(data []byte) (*SignedData, error) {
return &SignedData{sd: sd, data: data, digestOid: OIDDigestAlgorithmSHA1, contentTypeOid: OIDSignedData}, nil
}
// NewSignedDataWithDigest creates a new SignedData instance using the provided digest.
// It sets the isDigest field to true, indicating that the input is already a digest.
// Returns the SignedData instance or an error if the creation fails.
// NewSignedDataWithDigest creates a new SignedData structure with the provided digest.
// The digest is used to initialize the SignedData object, and the content is set to an empty ASN.1 RawValue.
// The function returns a pointer to the SignedData object and an error if any occurs.
func NewSignedDataWithDigest(digest []byte) (*SignedData, error) {
ci := contentInfo{
ContentType: OIDData,
@ -64,9 +64,10 @@ func NewSignedDataWithDigest(digest []byte) (*SignedData, error) {
return &SignedData{sd: sd, data: digest, digestOid: OIDDigestAlgorithmSHA1, contentTypeOid: OIDSignedData, isDigestProvided: true}, nil
}
// NewSMSignedData takes data and initializes a PKCS7 SignedData struct that is
// ready to be signed via AddSigner. The digest algorithm is set to SM3 by default
// and can be changed by calling SetDigestAlgorithm.
// NewSMSignedData creates a new SignedData object using the provided data
// and sets the appropriate OIDs for SM2 and SM3 algorithms.
// It returns a pointer to the SignedData object and an error if any occurs
// during the creation of the SignedData object.
func NewSMSignedData(data []byte) (*SignedData, error) {
sd, err := NewSignedData(data)
if err != nil {
@ -78,25 +79,28 @@ func NewSMSignedData(data []byte) (*SignedData, error) {
return sd, nil
}
// NewSMSignedDataWithDigest creates a new SignedData object using the provided digest.
// It calls the NewSMSignedData function with the given digest and sets the isDigest flag to true.
// If there is an error during the creation of the SignedData object, it returns the error.
// NewSMSignedDataWithDigest creates a new SignedData structure with the provided digest.
// The digest is expected to be a precomputed hash of the content to be signed.
// This function initializes the SignedData with the necessary OIDs for SM3 and SM2 algorithms.
func NewSMSignedDataWithDigest(digest []byte) (*SignedData, error) {
sd, err := NewSignedDataWithDigest(digest)
if err != nil {
return nil, err
ci := contentInfo{
ContentType: SM2OIDData,
Content: asn1.RawValue{}, // for sign digest, content is empty
}
sd.sd.ContentInfo.ContentType = SM2OIDData
sd.digestOid = OIDDigestAlgorithmSM3
sd.contentTypeOid = SM2OIDSignedData
return sd, nil
sd := signedData{
ContentInfo: ci,
Version: 1,
}
return &SignedData{sd: sd, data: digest, digestOid: OIDDigestAlgorithmSM3, contentTypeOid: SM2OIDSignedData, isDigestProvided: true}, nil
}
// SignerInfoConfig are optional values to include when adding a signer
// SignerInfoConfig contains configuration options for the signer information.
// It allows specifying additional signed and unsigned attributes, as well as
// an option to skip adding certificates to the payload.
type SignerInfoConfig struct {
ExtraSignedAttributes []Attribute
ExtraUnsignedAttributes []Attribute
SkipCertificates bool // Skip adding certificates to the payload
ExtraSignedAttributes []Attribute // Additional attributes to be included in the signed attributes.
ExtraUnsignedAttributes []Attribute // Additional attributes to be included in the unsigned attributes.
SkipCertificates bool // Skip adding certificates to the payload
}
type signedData struct {

View File

@ -170,7 +170,6 @@ func parseSignedData(data []byte) (*PKCS7, error) {
if err != nil {
return nil, err
}
// fmt.Printf("--> Signed Data Version %d\n", sd.Version)
var compound asn1.RawValue
var content unsignedData