PDF 签名 itext pkcs7 多签
PDF signature itext pkcs7 multi sign
我想在 pdf 文档上进行多重签名,就像在工作流程中一样。
我正在使用以下代码对我编写的 pdf 进行签名,效果很好。
获取hash
public String getHash() {
LOGGER.debug("PDFSigner.getHash : method invoked");
String pdfHashValue = null;
try {
int contentEstimated = PDFSigner.CONTENT_ESTIMATED;//8192
HashMap<PdfName, Integer> exc = new HashMap<>();
exc.put(PdfName.CONTENTS, contentEstimated * 2 + 2);
PdfSignature pdfSignature = new PdfSignature(PdfName.ADOBE_PPKLITE,
PdfName.ADBE_PKCS7_DETACHED);
pdfSignature.setReason(appearance.getReason());
pdfSignature.setLocation(appearance.getLocation());
pdfSignature.setContact(appearance.getContact());
pdfSignature.setDate(new PdfDate(appearance.getSignDate()));
appearance.setCryptoDictionary(pdfSignature);
appearance.preClose(exc);
InputStream data = appearance.getRangeStream();
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte buf[] = new byte[contentEstimated];
int n = 0;
while ((n = data.read(buf, 0, contentEstimated)) > 0) {
messageDigest.update(buf, 0, n);
}
byte hash[] = messageDigest.digest();
byte[] reqBytesdata = Hex.encode(hash);
pdfHashValue = new String(reqBytesdata, "UTF8");
} catch (Exception exp) {
LOGGER.error("PDFSigner error occured getHash", exp);
}
return pdfHashValue;
}
签署文件
//dSignature is the received encoded signature pkcs7 (SHA256).
//starts with MIIOWQYJKoZIhvcNAQcCo.....
public boolean doSign(String dSignature) throws IOException, DocumentException {
boolean pdfGenerationStatus = false;
try {
byte[] PKCS7Response = Base64.decode(dSignature
.getBytes("UTF8"));
byte[] paddedSig = new byte[PDFSigner.CONTENT_ESTIMATED];
System.arraycopy(PKCS7Response, 0, paddedSig, 0,
PKCS7Response.length);
PdfDictionary pdfDictionary = new PdfDictionary();
pdfDictionary.put(PdfName.CONTENTS,
new PdfString(paddedSig).setHexWriting(true));
appearance.close(pdfDictionary);
pdfGenerationStatus = true;
} catch (Exception exp) {
LOGGER.error("doSign ", exp);
}
return pdfGenerationStatus;
}
而且上面的代码工作正常。
我的新要求是添加多重签名。有什么方法可以重复使用此代码片段。
我经历了 this, and this 但运气不好。
除此之外我尝试的是,创建空白多个空白签名并尝试附加签名。但它导致创建损坏的文件。我还尝试使用 中提到的方法创建文件。 MakeSignature.signExternalContainer
还浏览了一个很棒的文档 PDF 文档的数字签名
用例就像
- 创建 pdf
- 生成文档哈希
- 发送到外部服务器
- 外部服务器将return一个pkcs7 base64编码的字符串
- 将签名附加到 pdf
更新
所做的代码更改是针对 'append mode',以下代码更改使我的代码支持多重签名,感谢@Paulo Soares,@mlk
private void initAppearanceAppend(String customerName) throws IOException, DocumentException {
System.out.println("PDFSigner.initAppearanceAppend");
PdfReader readerpdf = new PdfReader(this.getInputPdfFilePath());
int lastPageNumber = readerpdf.getNumberOfPages();
this.pdfSignatureMetaData.setPageNumber(lastPageNumber);
this.pdfSignatureMetaData.setSignerName(customerName);
//this.pdfSignatureMetaData.setPageNumber(PDFSigner.SIGNATURE_PAGE_NUMBER);
OutputStream fout = new FileOutputStream(this.outputPdfFilePath);
//PdfStamper stamperpdf = PdfStamper.createSignature(readerpdf, fout, '[=12=]'); OLD CODE WITHOUT APPEND MODE
PdfStamper stamperpdf = PdfStamper.createSignature(readerpdf, fout, '[=12=]', new File("E://temp"), true);
this.appearance = stamperpdf.getSignatureAppearance();
LOGGER.debug("PDFSigner.initAppearanceAppend : default configurations are made");
}
(您使用的是 iText 2.1.7,不是吗?这是旧版本,很多问题在 5 中解决了,在 7 中解决了更多问题。)
添加更多签名与添加第一个签名相同,只是使用追加方式。除非第一个签名是具有适当权限的经过认证的签名,否则只有最后一个签名会显示为有效,但它们都是有效的,只需提取一个修订版进行检查。
我想在 pdf 文档上进行多重签名,就像在工作流程中一样。 我正在使用以下代码对我编写的 pdf 进行签名,效果很好。
获取hash
public String getHash() {
LOGGER.debug("PDFSigner.getHash : method invoked");
String pdfHashValue = null;
try {
int contentEstimated = PDFSigner.CONTENT_ESTIMATED;//8192
HashMap<PdfName, Integer> exc = new HashMap<>();
exc.put(PdfName.CONTENTS, contentEstimated * 2 + 2);
PdfSignature pdfSignature = new PdfSignature(PdfName.ADOBE_PPKLITE,
PdfName.ADBE_PKCS7_DETACHED);
pdfSignature.setReason(appearance.getReason());
pdfSignature.setLocation(appearance.getLocation());
pdfSignature.setContact(appearance.getContact());
pdfSignature.setDate(new PdfDate(appearance.getSignDate()));
appearance.setCryptoDictionary(pdfSignature);
appearance.preClose(exc);
InputStream data = appearance.getRangeStream();
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte buf[] = new byte[contentEstimated];
int n = 0;
while ((n = data.read(buf, 0, contentEstimated)) > 0) {
messageDigest.update(buf, 0, n);
}
byte hash[] = messageDigest.digest();
byte[] reqBytesdata = Hex.encode(hash);
pdfHashValue = new String(reqBytesdata, "UTF8");
} catch (Exception exp) {
LOGGER.error("PDFSigner error occured getHash", exp);
}
return pdfHashValue;
}
签署文件
//dSignature is the received encoded signature pkcs7 (SHA256).
//starts with MIIOWQYJKoZIhvcNAQcCo.....
public boolean doSign(String dSignature) throws IOException, DocumentException {
boolean pdfGenerationStatus = false;
try {
byte[] PKCS7Response = Base64.decode(dSignature
.getBytes("UTF8"));
byte[] paddedSig = new byte[PDFSigner.CONTENT_ESTIMATED];
System.arraycopy(PKCS7Response, 0, paddedSig, 0,
PKCS7Response.length);
PdfDictionary pdfDictionary = new PdfDictionary();
pdfDictionary.put(PdfName.CONTENTS,
new PdfString(paddedSig).setHexWriting(true));
appearance.close(pdfDictionary);
pdfGenerationStatus = true;
} catch (Exception exp) {
LOGGER.error("doSign ", exp);
}
return pdfGenerationStatus;
}
而且上面的代码工作正常。
我的新要求是添加多重签名。有什么方法可以重复使用此代码片段。
我经历了 this,
除此之外我尝试的是,创建空白多个空白签名并尝试附加签名。但它导致创建损坏的文件。我还尝试使用 MakeSignature.signExternalContainer
还浏览了一个很棒的文档 PDF 文档的数字签名
用例就像
- 创建 pdf
- 生成文档哈希
- 发送到外部服务器
- 外部服务器将return一个pkcs7 base64编码的字符串
- 将签名附加到 pdf
更新
所做的代码更改是针对 'append mode',以下代码更改使我的代码支持多重签名,感谢@Paulo Soares,@mlk
private void initAppearanceAppend(String customerName) throws IOException, DocumentException {
System.out.println("PDFSigner.initAppearanceAppend");
PdfReader readerpdf = new PdfReader(this.getInputPdfFilePath());
int lastPageNumber = readerpdf.getNumberOfPages();
this.pdfSignatureMetaData.setPageNumber(lastPageNumber);
this.pdfSignatureMetaData.setSignerName(customerName);
//this.pdfSignatureMetaData.setPageNumber(PDFSigner.SIGNATURE_PAGE_NUMBER);
OutputStream fout = new FileOutputStream(this.outputPdfFilePath);
//PdfStamper stamperpdf = PdfStamper.createSignature(readerpdf, fout, '[=12=]'); OLD CODE WITHOUT APPEND MODE
PdfStamper stamperpdf = PdfStamper.createSignature(readerpdf, fout, '[=12=]', new File("E://temp"), true);
this.appearance = stamperpdf.getSignatureAppearance();
LOGGER.debug("PDFSigner.initAppearanceAppend : default configurations are made");
}
(您使用的是 iText 2.1.7,不是吗?这是旧版本,很多问题在 5 中解决了,在 7 中解决了更多问题。)
添加更多签名与添加第一个签名相同,只是使用追加方式。除非第一个签名是具有适当权限的经过认证的签名,否则只有最后一个签名会显示为有效,但它们都是有效的,只需提取一个修订版进行检查。