我们正在尝试使用apache pdfbox的分离签名功能。我们尝试了两种方法:
1.使用证书文件和私钥签名:在这种情况下,文档将得到完美的签名。
2.使用加密令牌签名:这里我们使用证书和从加密令牌收到的文档的签名哈希(文档签名),签名显示为无效(原因:文档自签名以来已被更改或破坏)。以下是代码段:
//fis = file input stream
// out = output file path
PDDocument document = PDDocument.load(fis);
FileOutputStream fos = new FileOutputStream(out);
PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName("Example User");
signature.setLocation("Los Angeles, CA");
signature.setReason("Testing");
Calendar date = Calendar.getInstance();
signature.setSignDate(date);
document.addSignature(signature);
ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(fos);
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
X509CertificateHolder cer = new X509CertificateHolder(euc); // euc = end user certificate in byte array form
X509Certificate cervalue = new JcaX509CertificateConverter().getCertificate(cer);
Certificate certChain[] = new Certificate[1];
certChain[0] = cervalue;
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner signer = new ContentSigner() {
@Override
public byte[] getSignature() {
return docSig; //byte[] docSig = byte array of signed hash received from crypto token
}
@Override
public OutputStream getOutputStream() {
return new ByteArrayOutputStream();
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
return new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WITHRSA");
}
};
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(signer, cervalue));
gen.addCertificates(new JcaCertStore(Arrays.asList(certChain)));
CMSProcessableInputStream msg = new CMSProcessableInputStream(externalSigning.getContent());
CMSSignedData signedData = gen.generate(msg, false);
byte[] cmsSignature = signedData.getEncoded();
externalSigning.setSignature(cmsSignature);
output.close();
以下是签名后创建的文档的屏幕截图:
Signed document
请提出我们要去哪里的错误。提前致谢。
最佳答案
如果哈希无效或签名无效或格式不正确,通常会出现错误消息“自签名以来,文档已被更改或损坏”。
在您的代码中,从何处获取“ docSig”?这是Web应用程序还是桌面应用程序?令牌已连接到服务器或客户端
请检查此SO Answer是否有用...
注意:您可以使用其他供应商提供的Browser Extension和Server库。
关于java - 使用apache pdfbox分离签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61790553/