在pdf上粘贴数字签名

时间:2017-01-24 08:57:52

标签: java pdf digital-signature

我正在尝试在pdf文档上粘贴数字签名。 我可以在pdf上粘贴签名,但签名不可见。我尝试了很多代码(如何在文档上显示签名)使签名可见,但不知何故无法做到。这是我用来在pdf上粘贴签名的代码。

String inputPDFlocation = INPUT_PDF_BASEPATH + inputPDFfilename;
String outputPDFlocation = OUTPUT_PDF_BASEPATH + inputPDFfilename;
PdfReader reader = new PdfReader(inputPDFlocation); // input PDF
PdfStamper stamper = PdfStamper.createSignature(reader, new FileOutputStream(outputPDFlocation), '\0', null, true);

// Finding the size of the page, and determining the location of signature:
Rectangle cropBox = reader.getCropBox(1); // Gets the 1st page
float width = 78;
float height = 34;
Rectangle rectangle;
// Top left
rectangle = new Rectangle(cropBox.getLeft(), cropBox.getTop(height), cropBox.getLeft(width), cropBox.getTop());

// Creating the appearance
PdfSignatureAppearance sap = stamper.getSignatureAppearance();
sap.setReason(SIGNATURE_REASON);
sap.setLocation(SIGNATURE_LOCATION);
sap.setVisibleSignature(rectangle, 1, sap.getNewSigName()); // new Rectangle(36, 748, 144, 780)

ExternalDigest externalDigest = new BouncyCastleDigest();
int estimatedSize = 8192;

PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
dic.setReason(sap.getReason());
dic.setLocation(sap.getLocation());
dic.setSignatureCreator(sap.getSignatureCreator());
dic.setContact(sap.getContact());

// Adding a buffer between the signature generation and the certificate start valid time.
Calendar cal = sap.getSignDate();
cal.add(Calendar.MINUTE, 1);
dic.setDate(new PdfDate(cal)); // time-stamp will over-rule this
sap.setCryptoDictionary(dic);

HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
exc.put(PdfName.CONTENTS, new Integer(estimatedSize * 2 + 2));
sap.preClose(exc);

String hashAlgorithm = DigestAlgorithms.SHA256;
InputStream data = sap.getRangeStream();
byte hash[] = DigestAlgorithms.digest(data, externalDigest.getMessageDigest(hashAlgorithm));

//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
    sb.append(Integer.toString((hash[i] & 0xff) + 0x100, 16).substring(1));
}


// 5. Setting Document hash
esign.setInput(sb.toString());




StringWriter eSignXML = new StringWriter();
try {
    JAXBContext.newInstance(Esign.class).createMarshaller().marshal(esign, eSignXML);
} catch (Exception ex) {
    logger.error("There was an error converting <Esign> XML to String: {}", ex.getMessage());
}


// 7. Get the digital signer, and sign the XML
DigitalSigner ds = getDigitalSigner();
if (ds == null) {
    return eSignResponse;
}
String signedEsignXML = ds.signXML(eSignXML.toString(), true);


// 8. Make a request
String responseXML = null;
Response response = HTTPClient.postRequestWithXmlPayloadOverTLS(eSignConfig.get(URL_ESIGN_SERVER), null, null, signedEsignXML, false);
if (response != null) {
    if (Response.Status.Family.familyOf(response.getStatus()) == Response.Status.Family.SUCCESSFUL) {
        responseXML = response.getEntity().toString();
    }
}


// 9. Parse the response
EsignResp esignResp = XMLUtil.parseXML(responseXML, EsignResp.class);
if (esignResp != null) {
        if (esignResp.getStatus() != null &&    esignResp.getStatus().equalsIgnoreCase("1")) {
        eSignResponse.setStatus(1);

        // If response is a SUCCESS, affix the signature ...

        String pkcs7Response = esignResp.getPkcs7Response();

        CMSSignedData cms = new CMSSignedData(Base64.decodeBase64(pkcs7Response.getBytes()));

        byte[] paddedSig = new byte[estimatedSize];
        System.arraycopy(cms.getEncoded(), 0, paddedSig, 0, cms.getEncoded().length);

        PdfDictionary dic2 = new PdfDictionary();
        dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
        sap.close(dic2);
}

1 个答案:

答案 0 :(得分:0)

您可以使用0x0矩形进行可视化:

// Finding the size of the page, and determining the location of signature:
Rectangle cropBox = reader.getCropBox(1); // Gets the 1st page
float width = 0;
float height = 0;
Rectangle rectangle;
// Top left
rectangle = new Rectangle(cropBox.getLeft(), cropBox.getTop(height), cropBox.getLeft(width), cropBox.getTop());
[...]    
sap.setVisibleSignature(rectangle, 1, sap.getNewSigName()); // new Rectangle(36, 748, 144, 780)

除非您为宽度和高度选择正值,否则您将永远不会看到签名可视化。