您使用的“签名”类型基于CMS(以前称为“PKCS#7”)。这是一种标准格式,用于使用加密或签名或两者来封装一些数据;这是递归的,因此您可以嵌套多个级别。
CMS 对象是ContentInfo
由这段 ASN.1 定义的结构:
ContentInfo ::= SEQUENCE {
contentType ContentType,
content [0] EXPLICIT ANY DEFINED BY contentType }
ContentType ::= OBJECT IDENTIFIER
当对象描述一个签名时,该contentType
字段包含“签名数据”的标识符,并且content
是一个SignedData
定义为的结构:
SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
signerInfos SignerInfos }
实际的加密签名在signerInfos
对象中,同时encapContentInfo
可能包含已签名的数据。这是重要的一点。EncapsulatedContentInfo
结构是:
EncapsulatedContentInfo ::= SEQUENCE {
eContentType ContentType,
eContent [0] EXPLICIT OCTET STRING OPTIONAL }
看到“ OPTIONAL
”了吗?这意味着 CMS 对象可能包含也可能不包含已签名的数据。
当 CMS 对象包含已签名的数据时,您最终会得到一个object,编码为字节数组(这就是使用 ASN.1 的要点:所有这些对象都可以随意编码和解码)。另一方面,如果 CMS 对象不包含已签名的数据,则这是一个分离的签名。当然,如果没有要签名的数据的副本,就无法对签名进行验证,因此如果签名是“分离的”,则必须有其他方式将数据本身传递给验证者。
分离式签名在使用S/MIME(S/MIME 可以描述为“电子邮件中的 CMS 对象”)的加密保护电子邮件的上下文中很流行,因为分离式签名随后作为电子邮件附件发送,而电子邮件文本内容保持不变:因此,电子邮件的内容仍然可以被完全不知道 S/MIME 可能是什么的软件读取,并且无法从 CMS-with-data 对象中提取数据。
在您的情况下,您必须生成验证者完成其工作所需的任何内容。这应该已经在您当前正在实施的协议中定义。可能,协议可能会告诉您要签名的数据已经通过另一个渠道提供给验证者;或者它可能会告诉您必须使用非分离的 CMS 签名对象。
如果没有明确定义的协议,而你正在制定它,那么这就是灾难的根源。我强烈希望不是这样。密码学很难使用,主要是因为没有办法测试你是否正确地使用了它。