我正在使用pdfbox 2.0.22覆盖和签署文档。覆盖层工作正常,但签名表示文档自签名后已被更改。
我在macbook上通过smb访问pdf,并在linux上开发。
这是覆盖和签名的(剥离)功能:
public MergePdfResponse MergePdfs(MergePdfRequest mergePdfRequest) throws IOException {
PdDocumentDetail basePdf = getPDFObject(getBasePdfBaseFileRequest());
PdDocumentDetail overlayPdf = getPDFObject(getSignatureBaseFileRequest());
PDDocument baseDocument = basePdf.pdDocument;
PDDocument overlayDocument = overlayPdf.pdDocument;
Iterator<PDPage> baseDocumentIterator = baseDocument.getPages().iterator();
Iterator<PDPage> signatureIterator = overlayDocument.getPages().iterator();
// code here to lock annotations per page
Overlay overlay = new Overlay();
overlay.setOverlayPosition(Overlay.Position.FOREGROUND);
overlay.setInputPDF(baseDocument);
overlay.setAllPagesOverlayPDF(overlayDocument);
Map<Integer, String> ovmap = new HashMap<Integer, String>();
overlay.overlay(ovmap);
if(baseDocument.getPages().getCount() < overlayDocument.getPages().getCount()) //missing audit trail pages, need to add.
{
for(int i=baseDocument.getPages().getCount();i<overlayDocument.getPages().getCount(); i++)
{
baseDocument.addPage(overlayDocument.getPages().get(i));
}
}
Config cfg = new Config();
String secret = "1234";
SetPermissions(baseDocument, secret, mergePdfRequest.canCopy);
PDDocument finalDocument;
try (ByteArrayOutputStream outputDocument = new ByteArrayOutputStream()) {
baseDocument.saveIncremental(outputDocument);
finalDocument = PDDocument.load(outputDocument.toByteArray(), secret);
baseDocument.close();
}
int accessPermissions = SigUtils.getMDPPermission(finalDocument);
if (accessPermissions == 1)
{
throw new IllegalStateException("No changes to the document are permitted due to DocMDP transform parameters dictionary");
}
PDSignature pdSignature = new PDSignature();
pdSignature.setName("QuicklySign");
pdSignature.setLocation("Cape Town, ZA");
pdSignature.setReason("Testing");
pdSignature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
pdSignature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
SignatureOptions signatureOptions = new SignatureOptions();
signatureOptions.setPreferredSignatureSize(SignatureOptions.DEFAULT_SIGNATURE_SIZE * 2);
finalDocument.addSignature(pdSignature, new PdfSigningInterface(), signatureOptions);
String filename = "examples/merge_pdf_examples/debug_signed.pdf";
if(mergePdfRequest.isDebug) {
filename = basePdf.filename + new Date().getTime() + ".ignore.pdf";
}
try (FileOutputStream output = new FileOutputStream(filename)) {
finalDocument.saveIncremental(output);
}
finalDocument.close();
overlayDocument.close();
return new MergePdfResponse(mergePdfRequest.baseGcsBucket, filenameForCompleted);
}
pdfsigninginterface的代码:
public class PdfSigningInterface implements SignatureInterface {
@Override
public byte[] sign(InputStream inputStream) throws IOException {
try {
Certificate[] certificateChain = GoogleCertificateProvider.INSTANCE.buildCertificateChain();
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
X509Certificate signingCertificate = (X509Certificate) certificateChain[0];
ContentSigner googleContentSigner = new GoogleContentSigner();
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().build()
).build(googleContentSigner, signingCertificate)
);
gen.addCertificates(new JcaCertStore(Arrays.asList(certificateChain)));
CMSProcessableInputStream msg = new CMSProcessableInputStream(inputStream);
CMSSignedData signedData = gen.generate(msg, false);
return signedData.getEncoded();
} catch (CMSException | OperatorCreationException | CertificateException e) {
throw new IOException(e);
}
}
}
googlecontentsigner:
public class GoogleContentSigner implements ContentSigner {
private final ByteArrayOutputStream outputStream;
private final AlgorithmIdentifier sigAlgId;
public GoogleContentSigner(){
this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WITHRSAANDMGF1");
this.outputStream = new ByteArrayOutputStream();
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
return this.sigAlgId;
}
@Override
public OutputStream getOutputStream() {
return this.outputStream;
}
@Override
public byte[] getSignature() {
try {
GoogleCertificateProvider kms = GoogleCertificateProvider.INSTANCE;
byte[] signedAttributeSet = outputStream.toByteArray();
Digest digest = kms.digestMessage(signedAttributeSet);
return kms.signDigestedContent(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("Unable to sign with KMS");
}
}
}
我的代码只是签名代码,而且我对pdfbox(或一般的pdf操作)非常陌生。我的目标是使用云kms生成签名pdf。
附有签名的pdf示例
为什么读者会这样说我的pdf签名是无效的?我直接登录到一个文件,并尝试在reader中打开它
暂无答案!
目前还没有任何答案,快来回答吧!