无法使用java中的pkcs#7和bouncyCastle签署zip文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法使用java中的pkcs#7和bouncyCastle签署zip文件相关的知识,希望对你有一定的参考价值。

我有一个程序来使用pkcs#7和bouncycastle来签名和验证文本和zip文件。我将以下字符串写入text和zip文件(包含base64编码的原始数据,SignedBytes和Certificate数据):

String finalmsg="<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
" +
                     "<Envelope>
" +"    <OrgContent>"+new String(Base64.encode(contentbytes))+"</OrgContent>
"+"    <Signature>"+new String(Base64.encode(signedBytes))+"</Signature>
"+"    <Certificate>"+
                    new String(Base64.encode(keyStore.getCertificate("CertName").getEncoded()))+"</Certificate>
"+"</Envelope>";

签名后能够完美地验证我的文本文件。也能够验证我的zip文件但是无法解压缩zip文件(我的zip文件出现意外结束错误)

下面是用于将签名消息写入文件的代码:

if(file.getName().contains(".zip")) {
byte[] b = finalmsg.getBytes(StandardCharsets.UTF_8);
try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(address+"SIGVERFILES/s2/"+name), 4096)) {
    out.write(b);
}
} else {
    FileWriter fw = new FileWriter(address+"SIGVERFILES/s2/"+name,true);
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write(finalmsg);
    bw.close();
}

还能够成功验证并解压缩由其他方签名的zip文件。所以我的验证码很好。我认为编写zip文件的方式有些不对劲。请不要介意缩进,并请求你帮我试着找出错在哪里?

如果需要更多代码段,请告诉我。

答案

您不能只将XML字符串写入文件,将其重命名为“whatever.zip”,并期望结果是有效的zip文件。 Zip是一种具有自己约束的二进制文件格式,其中一种是在文件开头以“PK”开头的幻数。

交换签名数据也有自己的约束,PKCS#7 SignedData也是规范化格式。

为了让您的生活更轻松,BouncyCastle提供了帮助程序类来生成有效,正确包装的签名数据。查看他们的文档和示例herehere

您需要决定生成附加签名还是分离签名:使用附加签名,ASN.1结构包含签名消息,因此您可以读取验证签名并从同一数据块读取有效内容(例如:RSA证书) 。使用分离的签名,您可以单独传输数据及其签名(但收件人需要两者才能验证签名 - 例如:可在公共FTP服务器上下载的签名文件)。通常,只需询问自己接收者是否可能想要使用有效负载而不首先验证其签名,即可回答问题。

以上是关于无法使用java中的pkcs#7和bouncyCastle签署zip文件的主要内容,如果未能解决你的问题,请参考以下文章

通过java读取PKCS7和.p12文件证书信息(subjectDN,vaildstartfrom,ValildTo ..)

Java和js使用AES/CBC/PKCS5Padding(或者7)得到相同的密文

Azure 函数无法加载文件或程序集“System.Security.Cryptography.Pkcs”

在没有库的情况下在 Java 中读取 PKCS#1 或 SPKI 公钥

无法使用AES / ECB / PKCS5Padding将加密方法从Java复制到PHP

Java、PHP 和 Objective-C 中的 pbkdf2 pkcs5 兼容散列