为什么我不能在 iText7 的 PKCS7.detached 之前使用 SHA1?

Why I can't use SHA1 before PKCS7.detached in iText7?

如图,现在可以实现1了,下面是我的签名成功代码,我用的是

pdfSigner.signExternalContainer(iExternalSignatureContainer, estimatedSize);

不是

 pdfSigner.signDetached();

:

public class PdfSignatureContainerExt implements IExternalSignatureContainer {

private MySignUtil mySignUtil;
public PdfSignatureContainerExt(MySignUtil mySignUtil){
    this.mySignUtil= mySignUtil;
}

/**
 * 
 * @param data , the data to sign
 * @return a container with the signature and other objects, like CRL and OCSP. The container will generally be a PKCS7 one.
 * @throws GeneralSecurityException
 */
@Override
public byte[] sign(InputStream data) throws GeneralSecurityException {

    byte[] dataBytes = streamToBytes(data);
    return  mySignUtil.signP7DetachData(dataBytes);

}

@Override
public void modifySigningDictionary(PdfDictionary signDic) {
    signDic.put(PdfName.Filter, PdfName.Adobe_PPKLite);
    signDic.put(PdfName.SubFilter, PdfName.Adbe_pkcs7_detached);
}}

为了实现2,我修改了输出结果无效的代码:

public class PdfSignatureContainerExt implements IExternalSignatureContainer {

private MySignUtil mySignUtil;
public PdfSignatureContainerExt(MySignUtil mySignUtil){
    this.mySignUtil= mySignUtil;
}


@Override
public byte[] sign(InputStream data) throws GeneralSecurityException {

        byte[] dataBytes = streamToBytes(data);
        //change here
        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);

        MessageDigest messageDigest = MessageDigest.getInstance("SHA1" , "BC");
        byte[] hash = messageDigest.digest(dataBytes);

        return  mySignUtil.signP7DetachData(hash);      
}

@Override
public void modifySigningDictionary(PdfDictionary signDic) {
    signDic.put(PdfName.Filter, PdfName.Adobe_PPKLite);
    //change here
    signDic.put(PdfName.SubFilter, PdfName.Adbe_pkcs7_sha1);
}}

并且输出符号结果失败,这是我失败的pdf。

invalid.pdf

您用来创建 adbe.pkcs7.detached CMS 签名容器的方法

return  mySignUtil.signP7DetachData(data);

(带有 InputStream data)创建容器的方式与您用来创建 adbe.pkcs7.sha1 CMS 容器

的方法一样
return  mySignUtil.signP7DetachData(hash);      

(带有 byte[] hash),至少这是您的示例文件所建议的。

这是错误的:正如 PDF 参考 1.7 所说:

  • adbe.pkcs7.detached: No data is encapsulated in the PKCS#7 signed-data field.
  • adbe.pkcs7.sha1: The SHA1 digest of the byte range is encapsulated in the PKCS#7 signed-data field with ContentInfo of type Data.

(第 8.7.2 节 "Signature Interoperability")

由于您在这两种情况下都使用了相同的功能来创建 CMS 容器,因此您留下了 PKCS#7 签名数据字段(可选的 eContent CMS SignedData 字段中的八位字节字符串 EncapsulatedContentInfo 是指)在您的 adbe.pkcs7.sha1 空容器中,这违反了规范。


PS:通常我会参考 ISO 32000 标准,但不幸的是,第 1 部分和第 2 部分中的相应部分已被更改为使内容介于更加不清楚和完全错误之间。不幸的是,当有人可以为 ISO 32000-2 提供输入时,我并没有想到这一点。

PPS:根本不应再使用 Ceterum censeo adbe.pkcs7.sha1。我们的验证代码明确没有实现这些签名的验证。