使用SHA-256的CMS签名在AS2传输中验证失败的技术求助
基于HTTP的AS2数字签名问题排查与解答
核心问题:签名验证失败的排查方向
- 证书链完整性检查:你用自签名命令生成的证书,需确认合作方Mendelson已将该自签名证书添加为信任根。同时验证PFX文件是否完整包含私钥与证书,执行以下命令检查:
确认输出包含openssl pkcs12 -info -in certificate.p12Private Key和Certificate条目。 - CMS签名必填属性缺失:AS2强制要求CMS签名包含
content-type、signing-time等Signed Attributes,你的C#代码未显式添加这些属性,需修改代码补充:signer.SignedAttributes.Add(new Pkcs9ContentType(content.ContentType)); signer.SignedAttributes.Add(new Pkcs9SigningTime()); - Multipart/Signed格式校验:AS2的
multipart/signed请求需严格符合RFC 2633规范,确保:- 请求头的
micalg值为sha-256(小写,与签名算法匹配) - 签名部分的Content-Type为
application/pkcs7-signature - 边界符、内容编码无格式错误
- 请求头的
用户疑问解答
1. 是否必须使用CMS?
是的,AS2传输的数字签名必须遵循CMS(RFC 5652,RFC 6211为更新版本)。直接对数据做RSA签名不符合AS2规范,因为AS2要求签名包含哈希算法、签名时间、证书链等元数据,这些都是CMS的核心组成部分,直接签名会被系统判定为无效格式,触发“哈希算法未被识别”错误。
2. 能否从零构建CMS?示例代码
从零构建CMS需手动处理ASN.1编码,生产环境不推荐,但可通过BouncyCastle库实现极简示例:
using Org.BouncyCastle.Cms; using Org.BouncyCastle.X509; using Org.BouncyCastle.Security; using Org.BouncyCastle.Pkcs; using System.IO; using System.Linq; public byte[] BuildCmsFromScratch(byte[] data, string p12Path, string password) { // 加载PFX证书与私钥 Pkcs12Store store = new Pkcs12Store(new FileStream(p12Path, FileMode.Open), password.ToCharArray()); string alias = store.Aliases.Cast<string>().First(a => store.IsKeyEntry(a)); AsymmetricKeyEntry keyEntry = store.GetKey(alias); X509CertificateEntry certEntry = store.GetCertificate(alias); // 构建CMS签名生成器 CmsSignedDataGenerator generator = new CmsSignedDataGenerator(); generator.AddSigner(keyEntry.Key, certEntry.Certificate, CmsSignedDataGenerator.DigestSha256); generator.AddCertificate(certEntry.Certificate); // 生成带Signed Attributes的CMS签名 CmsProcessableByteArray content = new CmsProcessableByteArray(data); CmsSignedData signedData = generator.Generate(content, true); return signedData.GetEncoded(); }
注意:必须开启Signed Attributes(Generate方法第二个参数为true),否则签名会被AS2系统拒绝。
3. Mendelson中“Use Algorithm Identifier Protection Attribute”的含义
该选项对应CMS规范的算法标识符保护属性(RFC 5652 §5.3),作用是:
- 将签名算法的OID(如SHA256-RSA的
1.2.840.113549.1.1.11)加入Signed Attributes进行哈希签名,防止攻击者篡改签名算法 - 启用该选项后,你的CMS签名必须包含此属性,否则Mendelson会验证失败
- 如需在C#代码中添加该属性,可补充以下代码:
Oid algorithmProtectionOid = new Oid("1.2.840.113549.1.9.16.2.15"); AsnEncodedData algorithmValue = new AsnEncodedData(new Oid("1.2.840.113549.1.1.11"), new byte[0]); signer.SignedAttributes.Add(new Pkcs9AttributeObject(algorithmProtectionOid, algorithmValue.RawData));
内容的提问来源于stack exchange,提问作者Makstvell
相关产品推荐
相关产品推荐

