我正在尝试使用HSM实现PDF文档的签名,但无法获得有效签名,并且不再失败。我搜索了存在的各种问题,但我没有看到我的代码存在问题。
我使用以下版本
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.47</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk15on</artifactId>
<version>1.47</version>
</dependency>
我的代码是:
public byte[] getHash() throws Exception {
reader = new PdfReader(new ByteArrayInputStream(content));
baos = new ByteArrayOutputStream();
stamper = PdfStamper.createSignature(reader, baos, '\0');
sap = stamper.getSignatureAppearance();
sap.setReason("Test");
sap.setLocation("On a server!");
sap.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
sap.setCertificate(x509Certificate);
dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
dic.setReason(sap.getReason());
dic.setLocation(sap.getLocation());
dic.setContact(sap.getContact());
dic.setDate(new PdfDate(sap.getSignDate()));
sap.setCryptoDictionary(dic);
exc = new HashMap<PdfName, Integer>();
exc.put(PdfName.CONTENTS, new Integer(8192 * 2 + 2));
sap.preClose(exc);
externalDigest = new ExternalDigest() {
@Override
public MessageDigest getMessageDigest(String hashAlgorithm)
throws GeneralSecurityException {
return DigestAlgorithms.getMessageDigest(hashAlgorithm, null);
}
};
chain = new X509Certificate[1];
chain[0] = x509Certificate;
sgn = new PdfPKCS7(null, chain, "SHA256", null, externalDigest, false);
data = sap.getRangeStream();
cal = Calendar.getInstance();
hash = DigestAlgorithms.digest(data, externalDigest.getMessageDigest("SHA256"));
sh = sgn.getAuthenticatedAttributeBytes(hash, cal, null, null, CryptoStandard.CMS);
sh = DigestAlgorithms.digest(new ByteArrayInputStream(sh), externalDigest.getMessageDigest("SHA256"));
return sh;
}
public void complateToSignature(byte[] signedHash) throws Exception {
sgn.setExternalDigest(Base64.decode(signedHash), null, "RSA");
encodedSig = sgn.getEncodedPKCS7(hash, cal, null, null, null, CryptoStandard.CMS);
paddedSig = new byte[8192];
System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);
PdfDictionary dic2 = new PdfDictionary();
dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
sap.close(dic2);
byte[] pdf = baos.toByteArray();
FileUtils.saveFileContent(pdf, Paths.get("pathFileDest.pdf"));
}
最后,我的测试代码是:
private void signPdf(X509Certificate certificate){
File pdf = new File("C:\\File8888.pdf");
FileInputStream is;
byte[] content = new byte[0];
try {
is = new FileInputStream(pdf);
content = new byte[is.available()];
is.read(content);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
PDFSignature1 operation = new PDFSignature1(content, certificate);
byte[] hash = new byte[0];
String encodeData = "";
try {
hash = operation.getHash();
//simule control for mobile signature.
encodeData = com.itextpdf.text.pdf.codec.Base64.encodeBytes(hash);
if (encodeData.length() != 44) {
throw new Exception("Sign to data must be 44 characters");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final String hashHex = toHex(encodeData);
final String hashSignat = signExternalService(hashHex);
try {
operation.complateToSignature(hashSignat.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
我们没有看到我们在这个过程中出错了。
我们非常感谢任何帮助或其他方式来执行此过程。
感谢。