0

我有以下java代码(BouncyCastle 1.48):

CMSSignedDataStreamGenerator generator = new CMSSignedDataStreamGenerator();
generator.addSignerInfoGenerator(signerInfoGenerator);
generator.addCertificates(certStore);
FileOutputStream fos = new FileOutputStream("D:\\Data\\Desktop\\Test\\singedData.txt");
OutputStream theSignedDataStream = generator.open(fos, true);

IOUtils.copy(new FileInputStream("D:\\Data\\Desktop\\Test\\unsignedData.txt"), theSignedDataStream);

现在:数据已签名并写入signedData.txt 文件。问题是某些字符写错了(数据是具有 base64 编码内容的 mime 容器)。以下是数据片段:

ICAgIDxOQU1FLUFERFJFU1M+CiAgICAgICAgICA8TkFNRT4KICAgICAgICAgICAg
PExpbmUtMzU+TXVzdGVya3VuZGUgUGV0ZXIgSHV???,???èiZXI8L0xpbmUtMzU+CiAgICAg
ICAgICA8L05BTUU+CiAgICAgICAgICA8U1RSRUVUPgogICAgICAgICAgICA8TGlu

哪里的???,???代表[EOT],[ETX]('传输结束'和'文本结束'的ascii控制字符。在原始源数据中,没有出现错误字符的地方:...SHV???, ???éiZX...原来是...SHViZHX...

第二个片段:

Content-Transfer-Encoding: base64
Content-Type: application/pdf
Content-[EOT]‚[ETX]Description: The PDF Title

有人可以帮我吗?我究竟做错了什么?

最好的问候,弗洛里安

4

1 回答 1

0

您了解 CMS SignedData 是 ASN.1 格式吗?这意味着有额外的字段和结构标签;您的原始数据封装在此结构中。如果您不想封装原始数据,而只是生成签名,则将 'encapsulate' 参数的 'false' 传递给 open()。即 generator.open(fos, false);

当然,您可能需要将原始数据与签名一起发送,具体取决于您要实现的目标。

如果您有兴趣,“每 1000 个字母”是由于生成器将您的数据“八位字节串”分解为 1000 字节块,这是 CMSSignedDataStreamGenerator 生成的 BER 编码的一部分(BER 是编码 ASN 的一种方式。 1 个结构,如 SignedData)。

我还会考虑您是否应该签署内容的 Base-64 编码,或者原始内容字节可能更合适。显然,任何试图验证您的签名的人都需要清楚签名的具体内容。

于 2013-05-28T08:30:55.990 回答