2018-8-10
Java iText 操作PDF
嵌入 javascript
OutputStream os;//pdf out stream
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null,true);
String jsString = "app.alert(event.change);";
stamper.addJavaScript( jsString);adobe 官方关于acrobat javascript主页 adobe 官方使用文档 adobe 官方使用文档下载
实例数字签名 + 弹窗警告
/**
* @param password 秘钥密码
* @param keyStorePath 秘钥文件路径
* @param signPdfSrc 签名的PDF文件
* @param signImage 签名图片文件
* @param x x坐标
* @param y y坐标
* @return
*/
public static byte[] sign(String password, String keyStorePath, String signPdfSrc, String signImage, float x, float y) {
File signPdfSrcFile = new File(signPdfSrc);
PdfReader reader = null;
ByteArrayOutputStream signPDFData = null;
PdfStamper stp = null;
FileInputStream fos = null;
try {
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());
fos = new FileInputStream(keyStorePath);
// 私钥密码 为Pkcs生成证书 是的私钥密码
ks.load(fos, password.toCharArray());
String alias = (String) ks.aliases().nextElement();
PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
reader = new PdfReader(signPdfSrc);
signPDFData = new ByteArrayOutputStream();
// 临时pdf文件
File temp = new File(signPdfSrcFile.getParent(), UUID.randomUUID() + ".pdf");
stp = PdfStamper.createSignature(reader, signPDFData, '\0', temp, true);
stp.setFullCompression();
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setReason("数字签名, 不可改变");//签名原因
// 使用png格式透明图片
Image image = Image.getInstance(signImage);
sap.setImageScale(0);
sap.setSignatureGraphic(image);
sap.setRenderingMode(RenderingMode.GRAPHIC);
// 是对应x轴和y轴坐标 和字段名
sap.setVisibleSignature(new Rectangle(x, y, x + image.getWidth(), y + image.getHeight() ), 1,
"field_name");
///注入脚本
String jsString = ""
+ "var sign = this.getField(\"field_name\");\r\n" + //根据字段 获得
"var stat = sign.signatureValidate();\r\n" + //验证
"app.alert( \"签名状态: \" + stat);";//参考: js_api_reference.rar 文档 Field -> field methods -> signatureValidate
stp.addJavaScript( jsString);
stp.getWriter().setCompressionLevel(5);
ExternalDigest digest = new BouncyCastleDigest();
ExternalSignature signature = new PrivateKeySignature(key, DigestAlgorithms.SHA512, provider.getName());
MakeSignature.signDetached(sap, digest, signature, chain, null, null, null, 0, CryptoStandard.CADES);
stp.close();
reader.close();
return signPDFData.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (signPDFData != null) {
try {
signPDFData.close();
} catch (IOException e) {
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
}
return null;
}- maven 依赖
<!-- PDF 签名 -->
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- 加密相关的-->
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk15on</artifactId>
<version>1.60</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.60</version>
</dependency>
验证数字签名
TODO https://blog.csdn.net/haoxiaoyong1014/article/details/80871639