我必须签名并将数据发送到服务器。使用Bouncy castle我已经生成了CMSSignedData对象。我是密码学的新手,据我所知,我必须将已签名的数据以及签名的数据发送到服务器。我必须将其作为单个文件发送。我可以使用
获取已签名的数据CMSProcessableByteArray cpby = (CMSProcessableByteArray) sigData.getSignedContent() ;
byte[] data = (byte[])cpby.getContent();
这里sigData是CMSSignedData对象
我认为代码
byte[] signed = sigData.getEncoded()
获取字节数组中的签名数据。
问题是创建包含数据和签名数据的文件的一般方法是什么。我只是添加两个字节数组吗?签名[]数组是否也包含数据?如果是这样,我如何从签名[]数组中检索数据。我问这个是因为我需要遵循类似的程序来检索服务器响应验证过程的数据和签名数据。
答案 0 :(得分:3)
您使用的“签名”类型基于CMS(以前称为“PKCS#7”)。这是用加密或签名或两者封装某些数据的标准格式;这是递归的,所以你可以嵌套几个级别。
CMS对象是由此ASN.1定义的ContentInfo
结构:
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对象包含已签名的数据时,您最终得到一个单个对象,编码为一个字节数组(这是使用ASN.1的重点:所有这些对象都可以随意编码和解码)。另一方面,如果CMS对象的不包含已签名的数据,则这是分离的签名。当然,如果没有要签名的数据副本,就无法执行签名的验证,因此如果签名是“分离的”,那么必须有其他方式来传达数据本身验证者。
分离签名在加密受保护的电子邮件的上下文中很受欢迎S/MIME(S / MIME可以描述为“电子邮件中的CMS对象”),因为分离的签名随后作为电子邮件附件发送,电子邮件文本内容未被触及:因此,电子邮件的内容仍然可以由软件读取,该软件完全不知道S / MIME可能是什么,并且无法从带有数据的CMS对象中提取数据。
在您的情况下,您必须生成验证者完成其工作所需的任何内容。这应该已经在您目前正在实施的协议中定义。可能,协议可能会告诉您,要签名的数据已经可以通过另一个通道提供给验证者;或者它可能会告诉您必须使用未分离的CMS签名对象。
如果没有明确定义的协议,并且你正在按照它去做,那么这就是灾难的秘诀。我强烈希望事实并非如此。密码学很难使用,主要是因为没有办法测试你是否正确使用它。
答案 1 :(得分:0)
首先,您需要知道服务器期望数据的确切格式。如果您使用PKCS#7 / CMS,则无需合并任何内容。
PKCS#7支持包装和分离签名。在第一种情况下,您将获得一个块中的签名数据和签名,并将此块发送到服务器。如果您创建了分离签名,那么您将拥有原始数据和单独的小签名块。
当原始数据必须保持可读时,使用正常分离的签名(因为包装数据会使目标读者无法读取,例如,如果您使用PKCS#7签署PDF文件,Acrobat将无法打开它正确)。所以我认为你应该在一个块中发送签名数据。