PDFBox:签名失败 "Can't write signature, not enough space"
PDFBox : Signature fails "Can't write signature, not enough space"
我在 JAVA 中使用 PDFBox 实现了签名功能。
我的代码的签名部分是:
ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(output);
byte[] cmsSignature = new byte[0];
try {
Certificate[] certificationChain = SignatureUtils.getCertificateChain(alias);
X509Certificate certificate = (X509Certificate) certificationChain[0];
PrivateKey privateKey = SignatureUtils.getSignaturePrivateKey(alias, password);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build())
.build(sha1Signer, certificate));
gen.addCertificates(new JcaCertStore(Arrays.asList(certificationChain)));
CMSProcessableInputStream msg = new CMSProcessableInputStream(externalSigning.getContent());
CMSSignedData signedData = gen.generate(msg, false);
if (tsaUrl != null && !tsaUrl.isEmpty()) {
ValidationTimeStamp validation;
validation = new ValidationTimeStamp(tsaUrl);
signedData = validation.addSignedTimeStamp(signedData);
}
cmsSignature = signedData.getEncoded();
if (logger.isDebugEnabled()) {
logger.debug("signature length = " + cmsSignature.length);
logger.debug("certificate = " + certificate.toString());
}
} catch (GeneralSecurityException | CMSException | OperatorCreationException | IOException e) {
throw new SignatureException(e.getMessage());
}
externalSigning.setSignature(cmsSignature);
如果我使用通过 keytool 命令生成的测试自动签名证书,一切正常。
问题是,当我使用真正经过认证的现有证书尝试此代码时,我得到了例外:
Caused by: java.io.IOException: Can't write signature, not enough space
at org.apache.pdfbox.pdfwriter.COSWriter.writeExternalSignature(COSWriter.java:797)
at org.apache.pdfbox.pdmodel.interactive.digitalsignature.SigningSupport.setSignature(SigningSupport.java:48)
我不知道为什么这不起作用...
如有任何帮助,我们将不胜感激! =)
在评论中你提到你得到了
signature length = 10721
在日志文件中并且您
didn't set any preferred size
PDFBox默认为签名保留0x2500字节。这是十进制的 9472 字节。因此,就像异常所说的那样,不够 space.
您可以在 document.addSignature
期间使用 SignatureOptions
对象设置 PDFBox 为签名保留的大小:
SignatureOptions signatureOptions = new SignatureOptions();
signatureOptions.setPreferredSignatureSize(20000);
document.addSignature(signature, signatureOptions);
我在 JAVA 中使用 PDFBox 实现了签名功能。
我的代码的签名部分是:
ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(output);
byte[] cmsSignature = new byte[0];
try {
Certificate[] certificationChain = SignatureUtils.getCertificateChain(alias);
X509Certificate certificate = (X509Certificate) certificationChain[0];
PrivateKey privateKey = SignatureUtils.getSignaturePrivateKey(alias, password);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build())
.build(sha1Signer, certificate));
gen.addCertificates(new JcaCertStore(Arrays.asList(certificationChain)));
CMSProcessableInputStream msg = new CMSProcessableInputStream(externalSigning.getContent());
CMSSignedData signedData = gen.generate(msg, false);
if (tsaUrl != null && !tsaUrl.isEmpty()) {
ValidationTimeStamp validation;
validation = new ValidationTimeStamp(tsaUrl);
signedData = validation.addSignedTimeStamp(signedData);
}
cmsSignature = signedData.getEncoded();
if (logger.isDebugEnabled()) {
logger.debug("signature length = " + cmsSignature.length);
logger.debug("certificate = " + certificate.toString());
}
} catch (GeneralSecurityException | CMSException | OperatorCreationException | IOException e) {
throw new SignatureException(e.getMessage());
}
externalSigning.setSignature(cmsSignature);
如果我使用通过 keytool 命令生成的测试自动签名证书,一切正常。
问题是,当我使用真正经过认证的现有证书尝试此代码时,我得到了例外:
Caused by: java.io.IOException: Can't write signature, not enough space
at org.apache.pdfbox.pdfwriter.COSWriter.writeExternalSignature(COSWriter.java:797)
at org.apache.pdfbox.pdmodel.interactive.digitalsignature.SigningSupport.setSignature(SigningSupport.java:48)
我不知道为什么这不起作用...
如有任何帮助,我们将不胜感激! =)
在评论中你提到你得到了
signature length = 10721
在日志文件中并且您
didn't set any preferred size
PDFBox默认为签名保留0x2500字节。这是十进制的 9472 字节。因此,就像异常所说的那样,不够 space.
您可以在 document.addSignature
期间使用 SignatureOptions
对象设置 PDFBox 为签名保留的大小:
SignatureOptions signatureOptions = new SignatureOptions();
signatureOptions.setPreferredSignatureSize(20000);
document.addSignature(signature, signatureOptions);