使用iText 8结合NexU实现PDF延迟签名的哈希格式匹配问题
iText 8生成NexU兼容的待签哈希方案
问题出在你对「待签数据」的理解偏差上——NexU的getDataToSign返回的不是单纯的PDF文件哈希,而是符合CMS/PAdES规范的ASN.1编码DigestInfo结构,而你自定义的GetBytesToSign大概率直接返回了裸哈希字节,格式完全不匹配,才导致Adobe提示BER解码错误。
iText 8完全可以生成和NexU格式一致的待签数据,具体操作如下:
一、先搞懂NexU要的是什么
NexU要求的待签数据是标准PKCS#7定义的DigestInfo结构,ASN.1编码后是这样的:
DigestInfo ::= SEQUENCE { digestAlgorithm DigestAlgorithmIdentifier, digest OCTET STRING }
简单说就是把PDF哈希值用指定算法标识打包成ASN.1格式,而不是直接传哈希裸字节。
二、用iText 8生成兼容格式的待签数据
别自己手动拼结构,iText的PdfSigner已经封装了所有符合规范的逻辑,直接用就行:
步骤1:初始化签名器并获取待签数据
PdfReader reader = new PdfReader("你的源PDF路径"); // 生成带签名占位符的临时PDF PdfSigner signer = new PdfSigner(reader, new FileOutputStream("临时PDF路径"), new StampingProperties().useAppendMode()); // 定义空签名容器(只用来生成待签数据结构,不做实际签名) IExternalSignatureContainer dummyContainer = new IExternalSignatureContainer() { @Override public byte[] sign(InputStream data) { return new byte[0]; // 空实现,后续替换成NexU的签名结果 } @Override public void modifySigningDictionary(PdfDictionary signDic) { // 配置签名字典,和NexU要求的格式对齐,比如用Adbe_pkcs7_detached signDic.put(PdfName.Filter, PdfName.Adobe_PPKLite); signDic.put(PdfName.SubFilter, PdfName.Adbe_pkcs7_detached); } }; // 重点:这里拿到的dataToSign就是和NexU的getDataToSign格式一致的字节流 byte[] dataToSign = signer.getDocumentBytesToSign(dummyContainer);
步骤2:传给NexU签名,再嵌入结果
把上面的dataToSign传给NexU的签名API,拿到返回的签名字节后,再用iText完成嵌入:
// 假设signatureBytes是NexU返回的完整CMS签名包 IExternalSignatureContainer realContainer = new IExternalSignatureContainer() { @Override public byte[] sign(InputStream data) { return signatureBytes; } @Override public void modifySigningDictionary(PdfDictionary signDic) { // 和之前的配置保持一致 signDic.put(PdfName.Filter, PdfName.Adobe_PPKLite); signDic.put(PdfName.SubFilter, PdfName.Adbe_pkcs7_detached); } }; // 完成签名嵌入 signer.signExternalContainer(realContainer, 8192);
三、避坑要点
- 算法必须对齐:iText配置的签名算法(比如SHA-256withRSA)要和NexU用的完全一样,不然DigestInfo里的算法标识不匹配,签名肯定无效。
- 别瞎改待签数据:拿到
dataToSign直接传NexU,不要自己做哈希再包装,iText已经帮你处理了PDF文档的哈希计算、签名属性构建、ASN.1编码全流程。 - 检查签名结果:如果还是报错,确认NexU返回的是完整的CMS签名包,而不是单纯的签名值——iText需要完整的PKCS#7结构才能正确嵌入PDF。
内容的提问来源于stack exchange,提问作者Alexandru Popa
相关产品推荐
相关产品推荐

