为什么pdfbox成功地签署了pdf文件,但当在reader中打开时,它说文件在签署后被更改了?

iq0todco  于 2021-09-13  发布在  Java
关注(0)|答案(0)|浏览(430)

我正在使用pdfbox 2.0.22覆盖和签署文档。覆盖层工作正常,但签名表示文档自签名后已被更改。
我在macbook上通过smb访问pdf,并在linux上开发。
这是覆盖和签名的(剥离)功能:

  1. public MergePdfResponse MergePdfs(MergePdfRequest mergePdfRequest) throws IOException {
  2. PdDocumentDetail basePdf = getPDFObject(getBasePdfBaseFileRequest());
  3. PdDocumentDetail overlayPdf = getPDFObject(getSignatureBaseFileRequest());
  4. PDDocument baseDocument = basePdf.pdDocument;
  5. PDDocument overlayDocument = overlayPdf.pdDocument;
  6. Iterator<PDPage> baseDocumentIterator = baseDocument.getPages().iterator();
  7. Iterator<PDPage> signatureIterator = overlayDocument.getPages().iterator();
  8. // code here to lock annotations per page
  9. Overlay overlay = new Overlay();
  10. overlay.setOverlayPosition(Overlay.Position.FOREGROUND);
  11. overlay.setInputPDF(baseDocument);
  12. overlay.setAllPagesOverlayPDF(overlayDocument);
  13. Map<Integer, String> ovmap = new HashMap<Integer, String>();
  14. overlay.overlay(ovmap);
  15. if(baseDocument.getPages().getCount() < overlayDocument.getPages().getCount()) //missing audit trail pages, need to add.
  16. {
  17. for(int i=baseDocument.getPages().getCount();i<overlayDocument.getPages().getCount(); i++)
  18. {
  19. baseDocument.addPage(overlayDocument.getPages().get(i));
  20. }
  21. }
  22. Config cfg = new Config();
  23. String secret = "1234";
  24. SetPermissions(baseDocument, secret, mergePdfRequest.canCopy);
  25. PDDocument finalDocument;
  26. try (ByteArrayOutputStream outputDocument = new ByteArrayOutputStream()) {
  27. baseDocument.saveIncremental(outputDocument);
  28. finalDocument = PDDocument.load(outputDocument.toByteArray(), secret);
  29. baseDocument.close();
  30. }
  31. int accessPermissions = SigUtils.getMDPPermission(finalDocument);
  32. if (accessPermissions == 1)
  33. {
  34. throw new IllegalStateException("No changes to the document are permitted due to DocMDP transform parameters dictionary");
  35. }
  36. PDSignature pdSignature = new PDSignature();
  37. pdSignature.setName("QuicklySign");
  38. pdSignature.setLocation("Cape Town, ZA");
  39. pdSignature.setReason("Testing");
  40. pdSignature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
  41. pdSignature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
  42. SignatureOptions signatureOptions = new SignatureOptions();
  43. signatureOptions.setPreferredSignatureSize(SignatureOptions.DEFAULT_SIGNATURE_SIZE * 2);
  44. finalDocument.addSignature(pdSignature, new PdfSigningInterface(), signatureOptions);
  45. String filename = "examples/merge_pdf_examples/debug_signed.pdf";
  46. if(mergePdfRequest.isDebug) {
  47. filename = basePdf.filename + new Date().getTime() + ".ignore.pdf";
  48. }
  49. try (FileOutputStream output = new FileOutputStream(filename)) {
  50. finalDocument.saveIncremental(output);
  51. }
  52. finalDocument.close();
  53. overlayDocument.close();
  54. return new MergePdfResponse(mergePdfRequest.baseGcsBucket, filenameForCompleted);
  55. }

pdfsigninginterface的代码:

  1. public class PdfSigningInterface implements SignatureInterface {
  2. @Override
  3. public byte[] sign(InputStream inputStream) throws IOException {
  4. try {
  5. Certificate[] certificateChain = GoogleCertificateProvider.INSTANCE.buildCertificateChain();
  6. CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
  7. X509Certificate signingCertificate = (X509Certificate) certificateChain[0];
  8. ContentSigner googleContentSigner = new GoogleContentSigner();
  9. gen.addSignerInfoGenerator(
  10. new JcaSignerInfoGeneratorBuilder(
  11. new JcaDigestCalculatorProviderBuilder().build()
  12. ).build(googleContentSigner, signingCertificate)
  13. );
  14. gen.addCertificates(new JcaCertStore(Arrays.asList(certificateChain)));
  15. CMSProcessableInputStream msg = new CMSProcessableInputStream(inputStream);
  16. CMSSignedData signedData = gen.generate(msg, false);
  17. return signedData.getEncoded();
  18. } catch (CMSException | OperatorCreationException | CertificateException e) {
  19. throw new IOException(e);
  20. }
  21. }
  22. }

googlecontentsigner:

  1. public class GoogleContentSigner implements ContentSigner {
  2. private final ByteArrayOutputStream outputStream;
  3. private final AlgorithmIdentifier sigAlgId;
  4. public GoogleContentSigner(){
  5. this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WITHRSAANDMGF1");
  6. this.outputStream = new ByteArrayOutputStream();
  7. }
  8. @Override
  9. public AlgorithmIdentifier getAlgorithmIdentifier() {
  10. return this.sigAlgId;
  11. }
  12. @Override
  13. public OutputStream getOutputStream() {
  14. return this.outputStream;
  15. }
  16. @Override
  17. public byte[] getSignature() {
  18. try {
  19. GoogleCertificateProvider kms = GoogleCertificateProvider.INSTANCE;
  20. byte[] signedAttributeSet = outputStream.toByteArray();
  21. Digest digest = kms.digestMessage(signedAttributeSet);
  22. return kms.signDigestedContent(digest);
  23. } catch (NoSuchAlgorithmException e) {
  24. e.printStackTrace();
  25. throw new RuntimeException("Unable to sign with KMS");
  26. }
  27. }
  28. }

我的代码只是签名代码,而且我对pdfbox(或一般的pdf操作)非常陌生。我的目标是使用云kms生成签名pdf。
附有签名的pdf示例
为什么读者会这样说我的pdf签名是无效的?我直接登录到一个文件,并尝试在reader中打开它

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题