Java源码示例:org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature
示例1
@Override
public void createSignature(PDSignatureField pdSignatureField, PDPage page, String signerName)
throws IOException
{
PDSignature pdSignature = new PDSignature();
PDAnnotationWidget widget = pdSignatureField.getWidgets().get(0);
pdSignatureField.setValue(pdSignature);
widget.setPage(page);
page.getAnnotations().add(widget);
if (!signerName.isEmpty())
{
pdSignature.setName(signerName);
}
pdfStructure.setPdSignature(pdSignature);
LOG.info("PDSignature has been created");
}
示例2
/**
* <a href="http://stackoverflow.com/questions/41767351/create-pkcs7-signature-from-file-digest">
* Create pkcs7 signature from file digest
* </a>
* <p>
* A minimal signing frame work merely requiring a {@link SignatureInterface}
* instance.
* </p>
*/
void sign(PDDocument document, OutputStream output, SignatureInterface signatureInterface) throws IOException
{
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");
signature.setSignDate(Calendar.getInstance());
document.addSignature(signature);
ExternalSigningSupport externalSigning =
document.saveIncrementalForExternalSigning(output);
// invoke external signature service
byte[] cmsSignature = signatureInterface.sign(externalSigning.getContent());
// set signature bytes received from the service
externalSigning.setSignature(cmsSignature);
}
示例3
/**
* <a href="https://stackoverflow.com/questions/52757037/how-to-generate-pkcs7-signature-from-digest">
* How to generate PKCS#7 signature from digest?
* </a>
* <p>
* Like {@link #sign(PDDocument, OutputStream, SignatureInterface)}, merely
* the subfilter now indicates a PAdES signature, not a legacy ISO 32000-1
* signature. The generated signature is invalid as it does not have an ESS
* signing certificate attribute.
* </p>
* @see #testSignPAdESWithSeparatedHashing()
*/
void signPAdES(PDDocument document, OutputStream output, SignatureInterface signatureInterface) throws IOException
{
PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ETSI_CADES_DETACHED);
signature.setName("Example User");
signature.setLocation("Los Angeles, CA");
signature.setReason("Testing");
signature.setSignDate(Calendar.getInstance());
document.addSignature(signature);
ExternalSigningSupport externalSigning =
document.saveIncrementalForExternalSigning(output);
// invoke external signature service
byte[] cmsSignature = signatureInterface.sign(externalSigning.getContent());
// set signature bytes received from the service
externalSigning.setSignature(cmsSignature);
}
示例4
/**
* <a href="http://stackoverflow.com/questions/41116833/pdf-signature-validation">
* PDF Signature Validation
* </a>
* <br/>
* <a href="https://drive.google.com/file/d/0BzEmZ9pRWLhPOUJSYUdlRjg2eEU/view?usp=sharing">
* SignatureVlidationTest.pdf
* </a>
* <p>
* The code completely ignores the <b>SubFilter</b> of the signature.
* It is appropriate for signatures with <b>SubFilter</b> values
* <b>adbe.pkcs7.detached</b> and <b>ETSI.CAdES.detached</b>
* but will fail for signatures with <b>SubFilter</b> values
* <b>adbe.pkcs7.sha1</b> and <b>adbe.x509.rsa.sha1</b>.
* </p>
* <p>
* The example document has been signed with a signatures with
* <b>SubFilter</b> value <b>adbe.pkcs7.sha1</b>.
* </p>
*/
@Test
public void testValidateSignatureVlidationTest() throws Exception
{
System.out.println("\nValidate signature in SignatureVlidationTest.pdf; original code.");
byte[] pdfByte;
PDDocument pdfDoc = null;
SignerInformationVerifier verifier = null;
try
{
pdfByte = IOUtils.toByteArray(this.getClass().getResourceAsStream("SignatureVlidationTest.pdf"));
pdfDoc = Loader.loadPDF(new ByteArrayInputStream(pdfByte));
PDSignature signature = pdfDoc.getSignatureDictionaries().get(0);
byte[] signatureAsBytes = signature.getContents(pdfByte);
byte[] signedContentAsBytes = signature.getSignedContent(pdfByte);
CMSSignedData cms = new CMSSignedData(new CMSProcessableByteArray(signedContentAsBytes), signatureAsBytes);
SignerInformation signerInfo = (SignerInformation) cms.getSignerInfos().getSigners().iterator().next();
X509CertificateHolder cert = (X509CertificateHolder) cms.getCertificates().getMatches(signerInfo.getSID())
.iterator().next();
verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider(new BouncyCastleProvider()).build(cert);
// result if false
boolean verifyRt = signerInfo.verify(verifier);
System.out.println("Verify result: " + verifyRt);
}
finally
{
if (pdfDoc != null)
{
pdfDoc.close();
}
}
}
示例5
/**
* <a href="https://stackoverflow.com/questions/57926872/signed-pdf-content-digest-that-was-calculated-during-verification-is-diffrent-th">
* Signed PDF content digest that was calculated during verification is diffrent than decripted digest from signature
* </a>
* <br/>
* <a href="https://drive.google.com/open?id=1UlOZOp-UYllK7Ra35dggccoWdhcb_Ntp">
* TEST-signed-pades-baseline-b.pdf
* </a>
* <p>
* The code here demonstrates how to retrieve the messageDigest
* signed attribute value from a signed PDF. For production use
* obviously some null checks are required.
* </p>
*/
@Test
public void testExtractMessageDigestAttributeForUser2893427() throws IOException, CMSException {
try ( InputStream resource = getClass().getResourceAsStream("TEST-signed-pades-baseline-b.pdf") ) {
byte[] bytes = IOUtils.toByteArray(resource);
PDDocument document = Loader.loadPDF(bytes);
List<PDSignature> signatures = document.getSignatureDictionaries();
PDSignature sig = signatures.get(0);
byte[] cmsBytes = sig.getContents(bytes);
CMSSignedData cms = new CMSSignedData(cmsBytes);
SignerInformation signerInformation = cms.getSignerInfos().iterator().next();
Attribute attribute = signerInformation.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_messageDigest);
ASN1Encodable value = attribute.getAttributeValues()[0];
System.out.printf("MessageDigest attribute value: %s\n", value);
}
}
示例6
private PDF(String name, byte[] content) {
this.content = content;
try (InputStream inputStream = new ByteArrayInputStream(content)) {
try (PDDocument pdf = PDDocument.load(inputStream)) {
this.text = new PDFTextStripper().getText(pdf);
this.numberOfPages = pdf.getNumberOfPages();
this.author = pdf.getDocumentInformation().getAuthor();
this.creationDate = pdf.getDocumentInformation().getCreationDate();
this.creator = pdf.getDocumentInformation().getCreator();
this.keywords = pdf.getDocumentInformation().getKeywords();
this.producer = pdf.getDocumentInformation().getProducer();
this.subject = pdf.getDocumentInformation().getSubject();
this.title = pdf.getDocumentInformation().getTitle();
this.encrypted = pdf.isEncrypted();
PDSignature signature = pdf.getLastSignatureDictionary();
this.signed = signature != null;
this.signerName = signature == null ? null : signature.getName();
this.signatureTime = signature == null ? null : signature.getSignDate();
}
}
catch (Exception e) {
throw new IllegalArgumentException("Invalid PDF file: " + name, e);
}
}
示例7
/**
* This will return the last signature from the field tree. Note that this may not be the
* last in time when empty signature fields are created first but signed after other fields.
*
* @return the last signature as <code>PDSignatureField</code>.
* @throws IOException if no document catalog can be found.
*/
public PDSignature getLastSignatureDictionary() throws IOException
{
List<PDSignature> signatureDictionaries = getSignatureDictionaries();
int size = signatureDictionaries.size();
if (size > 0)
{
return signatureDictionaries.get(size - 1);
}
return null;
}
示例8
/**
* Retrieve all signature dictionaries from the document.
*
* @return a <code>List</code> of <code>PDSignatureField</code>s
* @throws IOException if no document catalog can be found.
*/
public List<PDSignature> getSignatureDictionaries() throws IOException
{
List<PDSignature> signatures = new ArrayList<PDSignature>();
for (PDSignatureField field : getSignatureFields())
{
COSBase value = field.getCOSObject().getDictionaryObject(COSName.V);
if (value != null)
{
signatures.add(new PDSignature((COSDictionary)value));
}
}
return signatures;
}
示例9
/**
* Returns the signature contained in this field.
*
* @return A signature dictionary.
*/
public PDSignature getValue()
{
COSBase value = getCOSObject().getDictionaryObject(COSName.V);
if (value instanceof COSDictionary)
{
return new PDSignature((COSDictionary) value);
}
return null;
}
示例10
/**
* Returns the default value, if any.
*
* @return A signature dictionary.
*/
public PDSignature getDefaultValue()
{
COSBase value = getCOSObject().getDictionaryObject(COSName.DV);
if (value == null)
{
return null;
}
return new PDSignature((COSDictionary)value);
}
示例11
/**
* <a href="https://stackoverflow.com/questions/52829507/multiple-esign-using-pdfbox-2-0-12-java">
* Multiple esign using pdfbox 2.0.12 java?
* </a>
* <p>
* This test demonstrates how to create a single signature in multiple signature
* fields with one widget annotation each only referenced from a single page each
* only. (Actually there is an extra invisible signature; it is possible to get
* rid of it with some more code.)
* </p>
*/
@Test
public void testCreateSignatureWithMultipleVisualizations() throws IOException {
try ( InputStream resource = getClass().getResourceAsStream("/mkl/testarea/pdfbox2/analyze/test-rivu.pdf");
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "testSignedMultipleVisualizations.pdf"));
PDDocument pdDocument = Loader.loadPDF(resource) )
{
PDAcroForm acroForm = pdDocument.getDocumentCatalog().getAcroForm();
if (acroForm == null) {
pdDocument.getDocumentCatalog().setAcroForm(acroForm = new PDAcroForm(pdDocument));
}
acroForm.setSignaturesExist(true);
acroForm.setAppendOnly(true);
acroForm.getCOSObject().setDirect(true);
PDRectangle rectangle = new PDRectangle(100, 600, 300, 100);
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");
signature.setSignDate(Calendar.getInstance());
pdDocument.addSignature(signature, this);
for (PDPage pdPage : pdDocument.getPages()) {
addSignatureField(pdDocument, pdPage, rectangle, signature);
}
pdDocument.saveIncremental(result);
}
}
示例12
/**
* <a href="https://stackoverflow.com/questions/52829507/multiple-esign-using-pdfbox-2-0-12-java">
* Multiple esign using pdfbox 2.0.12 java?
* </a>
* <br/>
* <a href="https://drive.google.com/open?id=1DKSApmjrT424wT92yBdynKUkvR00x9i2">
* C10000000713071804294534.pdf
* </a>
* <p>
* This test demonstrates how to create a single signature in multiple signature
* fields with one widget annotation each only referenced from a single page each
* only. (Actually there is an extra invisible signature; it is possible to get
* rid of it with some more code.) It uses the test file provided by the OP.
* </p>
*/
@Test
public void testCreateSignatureWithMultipleVisualizationsC10000000713071804294534() throws IOException {
try ( InputStream resource = getClass().getResourceAsStream("C10000000713071804294534.pdf");
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "C10000000713071804294534-SignedMultipleVisualizations.pdf"));
PDDocument pdDocument = Loader.loadPDF(resource) )
{
PDAcroForm acroForm = pdDocument.getDocumentCatalog().getAcroForm();
if (acroForm == null) {
pdDocument.getDocumentCatalog().setAcroForm(acroForm = new PDAcroForm(pdDocument));
}
acroForm.setSignaturesExist(true);
acroForm.setAppendOnly(true);
acroForm.getCOSObject().setDirect(true);
PDRectangle rectangle = new PDRectangle(100, 600, 300, 100);
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");
signature.setSignDate(Calendar.getInstance());
pdDocument.addSignature(signature, this);
for (PDPage pdPage : pdDocument.getPages()) {
addSignatureField(pdDocument, pdPage, rectangle, signature);
}
pdDocument.saveIncremental(result);
}
}
示例13
/**
* <p>
* A minimal signing frame work merely requiring a {@link SignatureInterface}
* instance signing an existing field.
* </p>
* @see #testSignWithLocking()
*/
void signExistingFieldWithLock(PDDocument document, OutputStream output, SignatureInterface signatureInterface) throws IOException
{
PDSignatureField signatureField = document.getSignatureFields().get(0);
PDSignature signature = new PDSignature();
signatureField.setValue(signature);
COSBase lock = signatureField.getCOSObject().getDictionaryObject(COS_NAME_LOCK);
if (lock instanceof COSDictionary)
{
COSDictionary lockDict = (COSDictionary) lock;
COSDictionary transformParams = new COSDictionary(lockDict);
transformParams.setItem(COSName.TYPE, COSName.getPDFName("TransformParams"));
transformParams.setItem(COSName.V, COSName.getPDFName("1.2"));
transformParams.setDirect(true);
COSDictionary sigRef = new COSDictionary();
sigRef.setItem(COSName.TYPE, COSName.getPDFName("SigRef"));
sigRef.setItem(COSName.getPDFName("TransformParams"), transformParams);
sigRef.setItem(COSName.getPDFName("TransformMethod"), COSName.getPDFName("FieldMDP"));
sigRef.setItem(COSName.getPDFName("Data"), document.getDocumentCatalog());
sigRef.setDirect(true);
COSArray referenceArray = new COSArray();
referenceArray.add(sigRef);
signature.getCOSObject().setItem(COSName.getPDFName("Reference"), referenceArray);
}
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName("blablabla");
signature.setLocation("blablabla");
signature.setReason("blablabla");
signature.setSignDate(Calendar.getInstance());
document.addSignature(signature);
ExternalSigningSupport externalSigning =
document.saveIncrementalForExternalSigning(output);
// invoke external signature service
byte[] cmsSignature = signatureInterface.sign(externalSigning.getContent());
// set signature bytes received from the service
externalSigning.setSignature(cmsSignature);
}
示例14
/**
* <a href="http://stackoverflow.com/questions/41116833/pdf-signature-validation">
* PDF Signature Validation
* </a>
* <br/>
* <a href="https://drive.google.com/file/d/0BzEmZ9pRWLhPOUJSYUdlRjg2eEU/view?usp=sharing">
* SignatureVlidationTest.pdf
* </a>
* <p>
* This code also ignores the <b>SubFilter</b> of the signature,
* it is appropriate for signatures with <b>SubFilter</b> value
* <b>adbe.pkcs7.sha1</b> which the example document has been
* signed with.
* </p>
*/
@Test
public void testValidateSignatureVlidationTestAdbePkcs7Sha1() throws Exception
{
System.out.println("\nValidate signature in SignatureVlidationTest.pdf; special adbe.pkcs7.sha1 code.");
byte[] pdfByte;
PDDocument pdfDoc = null;
SignerInformationVerifier verifier = null;
try
{
pdfByte = IOUtils.toByteArray(this.getClass().getResourceAsStream("SignatureVlidationTest.pdf"));
pdfDoc = Loader.loadPDF(new ByteArrayInputStream(pdfByte));
PDSignature signature = pdfDoc.getSignatureDictionaries().get(0);
byte[] signatureAsBytes = signature.getContents(pdfByte);
CMSSignedData cms = new CMSSignedData(new ByteArrayInputStream(signatureAsBytes));
SignerInformation signerInfo = (SignerInformation) cms.getSignerInfos().getSigners().iterator().next();
X509CertificateHolder cert = (X509CertificateHolder) cms.getCertificates().getMatches(signerInfo.getSID())
.iterator().next();
verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider(new BouncyCastleProvider()).build(cert);
boolean verifyRt = signerInfo.verify(verifier);
System.out.println("Verify result: " + verifyRt);
byte[] signedContentAsBytes = signature.getSignedContent(pdfByte);
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] calculatedDigest = md.digest(signedContentAsBytes);
byte[] signedDigest = (byte[]) cms.getSignedContent().getContent();
System.out.println("Document digest equals: " + Arrays.equals(calculatedDigest, signedDigest));
}
finally
{
if (pdfDoc != null)
{
pdfDoc.close();
}
}
}
示例15
private boolean containsFilledSignature(PDDocument pdDocument) {
try {
List<PDSignature> signatures = pdDocument.getSignatureDictionaries();
for (PDSignature pdSignature : signatures) {
if (pdSignature.getCOSObject().containsKey(COSName.BYTERANGE)) {
return true;
}
}
return false;
} catch (IOException e) {
LOG.warn("Cannot read the existing signature(s)", e);
return false;
}
}
示例16
/**
* Set the access permissions granted for this document in the DocMDP transform
* parameters dictionary. Details are described in the table "Entries in the
* DocMDP transform parameters dictionary" in the PDF specification.
*
* @param doc The document.
* @param signature The signature object.
* @param accessPermissions The permission value (1, 2 or 3).
*/
public void setMDPPermission(PDDocument doc, PDSignature signature, int accessPermissions) {
COSDictionary sigDict = signature.getCOSObject();
// DocMDP specific stuff
COSDictionary transformParameters = new COSDictionary();
transformParameters.setItem(COSName.TYPE, COSName.getPDFName("TransformParams"));
transformParameters.setInt(COSName.P, accessPermissions);
transformParameters.setName(COSName.V, "1.2");
transformParameters.setNeedToBeUpdated(true);
COSDictionary referenceDict = new COSDictionary();
referenceDict.setItem(COSName.TYPE, COSName.getPDFName("SigRef"));
referenceDict.setItem("TransformMethod", COSName.DOCMDP);
referenceDict.setItem("TransformParams", transformParameters);
referenceDict.setNeedToBeUpdated(true);
COSArray referenceArray = new COSArray();
referenceArray.add(referenceDict);
sigDict.setItem("Reference", referenceArray);
referenceArray.setNeedToBeUpdated(true);
// Document Catalog
COSDictionary catalogDict = doc.getDocumentCatalog().getCOSObject();
COSDictionary permsDict = new COSDictionary();
catalogDict.setItem(COSName.PERMS, permsDict);
permsDict.setItem(COSName.DOCMDP, signature);
catalogDict.setNeedToBeUpdated(true);
permsDict.setNeedToBeUpdated(true);
}
示例17
@Test
public void vri() throws Exception {
String path = "/validation/Signature-P-HU_MIC-3.pdf";
String vriValue = "C41B1DBFE0E816D8A6F99A9DB98FD43960A5CF45";
PDDocument pdDoc = PDDocument.load(getClass().getResourceAsStream(path));
List<PDSignature> signatureDictionaries = pdDoc.getSignatureDictionaries();
assertTrue(Utils.isCollectionNotEmpty(signatureDictionaries));
PDSignature pdSignature = signatureDictionaries.get(0);
byte[] contents = pdSignature.getContents(getClass().getResourceAsStream(path));
byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA1, contents);
assertEquals(vriValue, Utils.upperCase(Utils.toHex(digest)));
// We can't use CMSSignedData, the pdSignature content is trimmed (000000)
}
示例18
/**
* Sets the value of this field to be the given signature.
*
* @param value is the PDSignatureField
*/
public void setValue(PDSignature value) throws IOException
{
getCOSObject().setItem(COSName.V, value);
applyChange();
}
示例19
@Override
public String getValueAsString()
{
PDSignature signature = getValue();
return signature != null ? signature.toString() : "";
}
示例20
/**
* Gets PDSignature
* @return the signature
*/
public PDSignature getPdSignature()
{
return pdSignature;
}
示例21
/**
* Sets PDSignatureField
* @param pdSignature
*/
public void setPdSignature(PDSignature pdSignature)
{
this.pdSignature = pdSignature;
}
示例22
public void testTimeStampOnly() {
String filePath = "caminho do arquivo";
PDDocument document;
try {
document = PDDocument.load(new File(filePath));
Timestamp varTimeStamp = null;
for (PDSignature sig : document.getSignatureDictionaries()) {
COSDictionary sigDict = sig.getCOSObject();
COSString contents = (COSString) sigDict.getDictionaryObject(COSName.CONTENTS);
FileInputStream fis = new FileInputStream(filePath);
byte[] buf = null;
try {
buf = sig.getSignedContent(fis);
} finally {
fis.close();
}
CAdESTimeStampSigner varCAdESTimeStampSigner = new CAdESTimeStampSigner();
varTimeStamp = varCAdESTimeStampSigner.checkTimeStampPDFWithContent(contents.getBytes(), buf);
}
if (varTimeStamp != null){
System.out.println("Carimbo do tempo");
System.out.println(varTimeStamp.getTimeStampAuthorityInfo());
System.out.println(varTimeStamp.getSerialNumber());
System.out.println(varTimeStamp.getCertificates());
System.out.println(varTimeStamp.getTimeStamp());
}
assertTrue(true);
} catch (IOException e) {
e.printStackTrace();
assertTrue(false);
}
}
示例23
public void testValidateSignatureVlidationTestAdbePkcs7Sha1() throws Exception
{
String filePath = "caminho arquivo";
byte[] pdfByte;
PDDocument pdfDoc = null;
SignerInformationVerifier verifier = null;
try
{
//pdfByte = IOUtils.toByteArray(this.getClass().getResourceAsStream("Teste_AI_Assinado_Assinador_Livre.pdf"));
pdfDoc = PDDocument.load(new File(filePath));
PDSignature signature = pdfDoc.getSignatureDictionaries().get(0);
byte[] signedContentAsBytes = signature.getSignedContent(new FileInputStream(filePath));
byte[] signatureAsBytes = signature.getContents(new FileInputStream(filePath));
PAdESChecker checker = new PAdESChecker();
checker.checkDetachedSignature(signedContentAsBytes, signatureAsBytes);
CMSSignedData cms = new CMSSignedData(new ByteArrayInputStream(signatureAsBytes));
SignerInformation signerInfo = (SignerInformation) cms.getSignerInfos().getSigners().iterator().next();
@SuppressWarnings("unchecked")
X509CertificateHolder cert = (X509CertificateHolder) cms.getCertificates().getMatches(signerInfo.getSID())
.iterator().next();
verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider(new BouncyCastleProvider()).build(cert);
boolean verifyRt = signerInfo.verify(verifier);
System.out.println("Verify result: " + verifyRt);
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] calculatedDigest = md.digest(signedContentAsBytes);
byte[] signedDigest = (byte[]) cms.getSignedContent().getContent();
System.out.println("Document digest equals: " + Arrays.equals(calculatedDigest, signedDigest));
}
finally
{
if (pdfDoc != null)
{
pdfDoc.close();
}
}
}
示例24
public static byte[] sign(PDDocument doc, String CERT_FILE, char[] ALIAS_PASS, String IMAGE_FILE) throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
IOException, UnrecoverableKeyException {
System.out.println("Document pages ? " + doc.getNumberOfPages());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
// ks.load(VisibleSignature.class.getResourceAsStream(CERT_FILE), ALIAS_PASS);
ks.load(new FileInputStream(CERT_FILE), ALIAS_PASS);
System.out.println("KeyStore is null ? " + (ks == null));
VisibleSignature vs = new VisibleSignature(ks, ALIAS_PASS.clone());
InputStream is = VisibleSignature.class.getResourceAsStream(IMAGE_FILE);
int page = 1;
vs.setVisibleSignDesigner(doc, 0, 0, -50, is, page);
is.close();
vs.setVisibleSignatureProperties("Test", "Test", "Test", 0, page, true);
PDSignature signature = new PDSignature();
PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
System.out.println("Acroform is null ? " + (acroForm == null));
if (acroForm != null)
System.out.println("Acroform getNeedAppearances ? " + (acroForm.getNeedAppearances()));
if (acroForm != null && acroForm.getNeedAppearances())
if (acroForm.getFields().isEmpty())
acroForm.getCOSObject().removeItem(COSName.NEED_APPEARANCES);
else
System.out.println("/NeedAppearances is set, signature may be ignored by Adobe Reader");
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
if (vs.visibleSignatureProperties != null) {
vs.visibleSignatureProperties.buildSignature();
signature.setName(vs.visibleSignatureProperties.getSignerName());
signature.setLocation(vs.visibleSignatureProperties.getSignerLocation());
signature.setReason(vs.visibleSignatureProperties.getSignatureReason());
System.out.println("SignerName " + vs.visibleSignatureProperties.getSignerName());
}
signature.setSignDate(Calendar.getInstance());
vs.signatureOptions = new SignatureOptions();
vs.signatureOptions.setVisualSignature(vs.visibleSignatureProperties.getVisibleSignature());
vs.signatureOptions.setPage(vs.visibleSignatureProperties.getPage() - 1);
// doc.addSignature(signature, vs.signatureOptions);
// using this overload instead fixes the issue.
doc.addSignature(signature, vs, vs.signatureOptions);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.saveIncremental(baos);
doc.close();
IOUtils.closeQuietly(vs.signatureOptions);
byte[] content = baos.toByteArray();
System.out.println("Content length: >>>>>>>>>>>>>>>>>>> " + content.length);
return content;
}
示例25
/**
* <p>
* A minimal signing frame work merely requiring a {@link SignatureInterface}
* instance signing an existing field and actually locking fields the transform
* requires to be locked.
* </p>
* @see #signExistingFieldWithLock(PDDocument, OutputStream, SignatureInterface)
*/
void signAndLockExistingFieldWithLock(PDDocument document, OutputStream output, SignatureInterface signatureInterface) throws IOException
{
PDSignatureField signatureField = document.getSignatureFields().get(0);
PDSignature signature = new PDSignature();
signatureField.setValue(signature);
COSBase lock = signatureField.getCOSObject().getDictionaryObject(COS_NAME_LOCK);
if (lock instanceof COSDictionary)
{
COSDictionary lockDict = (COSDictionary) lock;
COSDictionary transformParams = new COSDictionary(lockDict);
transformParams.setItem(COSName.TYPE, COSName.getPDFName("TransformParams"));
transformParams.setItem(COSName.V, COSName.getPDFName("1.2"));
transformParams.setDirect(true);
COSDictionary sigRef = new COSDictionary();
sigRef.setItem(COSName.TYPE, COSName.getPDFName("SigRef"));
sigRef.setItem(COSName.getPDFName("TransformParams"), transformParams);
sigRef.setItem(COSName.getPDFName("TransformMethod"), COSName.getPDFName("FieldMDP"));
sigRef.setItem(COSName.getPDFName("Data"), document.getDocumentCatalog());
sigRef.setDirect(true);
COSArray referenceArray = new COSArray();
referenceArray.add(sigRef);
signature.getCOSObject().setItem(COSName.getPDFName("Reference"), referenceArray);
final Predicate<PDField> shallBeLocked;
final COSArray fields = lockDict.getCOSArray(COSName.FIELDS);
final List<String> fieldNames = fields == null ? Collections.emptyList() :
fields.toList().stream().filter(c -> (c instanceof COSString)).map(s -> ((COSString)s).getString()).collect(Collectors.toList());
final COSName action = lockDict.getCOSName(COSName.getPDFName("Action"));
if (action.equals(COSName.getPDFName("Include"))) {
shallBeLocked = f -> fieldNames.contains(f.getFullyQualifiedName());
} else if (action.equals(COSName.getPDFName("Exclude"))) {
shallBeLocked = f -> !fieldNames.contains(f.getFullyQualifiedName());
} else if (action.equals(COSName.getPDFName("All"))) {
shallBeLocked = f -> true;
} else { // unknown action, lock nothing
shallBeLocked = f -> false;
}
lockFields(document.getDocumentCatalog().getAcroForm().getFields(), shallBeLocked);
}
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName("blablabla");
signature.setLocation("blablabla");
signature.setReason("blablabla");
signature.setSignDate(Calendar.getInstance());
document.addSignature(signature);
ExternalSigningSupport externalSigning =
document.saveIncrementalForExternalSigning(output);
// invoke external signature service
byte[] cmsSignature = signatureInterface.sign(externalSigning.getContent());
// set signature bytes received from the service
externalSigning.setSignature(cmsSignature);
}
示例26
private byte[] signDocumentAndReturnDigest(final PAdESCommonParameters parameters, final byte[] signatureBytes,
final OutputStream fileOutputStream, final PDDocument pdDocument) {
final MessageDigest digest = DSSUtils.getMessageDigest(parameters.getDigestAlgorithm());
SignatureInterface signatureInterface = new SignatureInterface() {
@Override
public byte[] sign(InputStream content) throws IOException {
byte[] b = new byte[4096];
int count;
while ((count = content.read(b)) > 0) {
digest.update(b, 0, count);
}
return signatureBytes;
}
};
final PDSignature pdSignature = createSignatureDictionary(parameters, pdDocument);
try (SignatureOptions options = new SignatureOptions()) {
options.setPreferredSignatureSize(parameters.getContentSize());
SignatureImageParameters imageParameters = parameters.getImageParameters();
if (imageParameters != null && signatureDrawerFactory != null) {
PdfBoxSignatureDrawer signatureDrawer = (PdfBoxSignatureDrawer) signatureDrawerFactory
.getSignatureDrawer(imageParameters);
signatureDrawer.init(imageParameters, pdDocument, options);
signatureDrawer.draw();
}
pdDocument.addSignature(pdSignature, signatureInterface, options);
// the document needs to have an ID, if not the current system time is used,
// and then the digest of the signed data will be different
if (pdDocument.getDocumentId() == null) {
pdDocument.setDocumentId(parameters.getSigningDate().getTime());
}
checkEncryptedAndSaveIncrementally(pdDocument, fileOutputStream, parameters);
return digest.digest();
} catch (IOException e) {
throw new DSSException(e);
}
}
示例27
/**
* <p>
* <b>(This is a new feature for 2.0.3. The API for external signing might change based on feedback after release!)</b>
* <p>
* Save PDF incrementally without closing for external signature creation scenario. The general
* sequence is:
* <pre>
* PDDocument pdDocument = ...;
* OutputStream outputStream = ...;
* SignatureOptions signatureOptions = ...; // options to specify fine tuned signature options or null for defaults
* PDSignature pdSignature = ...;
*
* // add signature parameters to be used when creating signature dictionary
* pdDocument.addSignature(pdSignature, signatureOptions);
* // prepare PDF for signing and obtain helper class to be used
* ExternalSigningSupport externalSigningSupport = pdDocument.saveIncrementalForExternalSigning(outputStream);
* // get data to be signed
* InputStream dataToBeSigned = externalSigningSupport.getContent();
* // invoke signature service
* byte[] signature = sign(dataToBeSigned);
* // set resulted CMS signature
* externalSigningSupport.setSignature(signature);
*
* // last step is to close the document
* pdDocument.close();
* </pre>
* <p>
* Note that after calling this method, only {@code close()} method may invoked for
* {@code PDDocument} instance and only AFTER {@link ExternalSigningSupport} instance is used.
* </p>
*
* @param output stream to write the final PDF. It will be closed when the
* document is closed. It <i><b>must never</b></i> point to the source file
* or that one will be harmed!
* @return instance to be used for external signing and setting CMS signature
* @throws IOException if the output could not be written
* @throws IllegalStateException if the document was not loaded from a file or a stream or
* signature options were not set.
*/
public ExternalSigningSupport saveIncrementalForExternalSigning(OutputStream output) throws IOException
{
if (pdfSource == null)
{
throw new IllegalStateException("document was not loaded from a file or a stream");
}
// PDFBOX-3978: getLastSignatureDictionary() not helpful if signing into a template
// that is not the last signature. So give higher priority to signature with update flag.
PDSignature foundSignature = null;
for (PDSignature sig : getSignatureDictionaries())
{
foundSignature = sig;
if (sig.getCOSObject().isNeedToBeUpdated())
{
break;
}
}
int[] byteRange = foundSignature.getByteRange();
if (!Arrays.equals(byteRange, RESERVE_BYTE_RANGE))
{
throw new IllegalStateException("signature reserve byte range has been changed "
+ "after addSignature(), please set the byte range that existed after addSignature()");
}
COSWriter writer = new COSWriter(output, pdfSource);
writer.write(this);
signingSupport = new SigningSupport(writer);
return signingSupport;
}
示例28
/**
* Add parameters of signature to be created externally using default signature options. See
* {@link #saveIncrementalForExternalSigning(OutputStream)} method description on external
* signature creation scenario details.
* <p>
* Only one signature may be added in a document. To sign several times,
* load document, add signature, save incremental and close again.
*
* @param sigObject is the PDSignatureField model
* @throws IOException if there is an error creating required fields
* @throws IllegalStateException if one attempts to add several signature
* fields.
*/
public void addSignature(PDSignature sigObject) throws IOException
{
addSignature(sigObject, new SignatureOptions());
}
示例29
/**
* Add parameters of signature to be created externally. See
* {@link #saveIncrementalForExternalSigning(OutputStream)} method description on external
* signature creation scenario details.
* <p>
* Only one signature may be added in a document. To sign several times,
* load document, add signature, save incremental and close again.
*
* @param sigObject is the PDSignatureField model
* @param options signature options
* @throws IOException if there is an error creating required fields
* @throws IllegalStateException if one attempts to add several signature
* fields.
*/
public void addSignature(PDSignature sigObject, SignatureOptions options) throws IOException
{
addSignature(sigObject, null, options);
}
示例30
/**
* Add a signature to be created using the instance of given interface.
* <p>
* Only one signature may be added in a document. To sign several times,
* load document, add signature, save incremental and close again.
*
* @param sigObject is the PDSignatureField model
* @param signatureInterface is an interface whose implementation provides
* signing capabilities. Can be null if external signing if used.
* @throws IOException if there is an error creating required fields
* @throws IllegalStateException if one attempts to add several signature
* fields.
*/
public void addSignature(PDSignature sigObject, SignatureInterface signatureInterface) throws IOException
{
addSignature(sigObject, signatureInterface, new SignatureOptions());
}