您好,我对 java 和使用 itext 还是很陌生。这个想法是在pdf中制作数字签名。源代码来自这里,对路径进行了一些调整..
package signaturefield;
public class Signaturefield {
/** The resulting PDF */
public static String ORIGINAL = "c:/Users/example.pdf";
/** The resulting PDF */
public static String SIGNED1 = "c:/Users/signed_1.pdf";
/** The resulting PDF */
public static String SIGNED2 = "c:/Users/signed_2.pdf";
/** One of the resources. */
public static final String RESOURCE
= "C:/Users/watermark.png";
/**
* A properties file that is PRIVATE.
* You should make your own properties file and adapt this line.
*/
public static String PATH = "c:/Users/key.properties";
/** Some properties used when signing. */
public static Properties properties = new Properties();
private PrivateKey pk;
/**
* Creates a PDF document.
* @param filename the path to the new PDF document
* @throws DocumentException
* @throws IOException
*/
public void createPdf(String filename) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World!"));
PdfFormField field = PdfFormField.createSignature(writer);
field.setWidget(new Rectangle(72, 732, 144, 780), PdfAnnotation.HIGHLIGHT_INVERT);
field.setFieldName("mySig");
field.setFlags(PdfAnnotation.FLAGS_PRINT);
field.setPage();
field.setMKBorderColor(BaseColor.BLACK);
field.setMKBackgroundColor(BaseColor.WHITE);
PdfAppearance tp = PdfAppearance.createAppearance(writer, 72, 48);
tp.rectangle(0.5f, 0.5f, 71.5f, 47.5f);
tp.stroke();
field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
writer.addAnnotation(field);
// step 5
document.close();
}
/**
* Manipulates a PDF file src with the file dest as result
* @param src the original PDF
* @param dest the resulting PDF
* @throws GeneralSecurityException
* @throws IOException
* @throws DocumentException
* @throws FileNotFoundException
* @throws KeyStoreException
* @throws Exception
*/
public void signPdf(String src, String dest, boolean certified, boolean graphic) throws GeneralSecurityException, IOException, DocumentException {
// private key and certificate
String path = properties.getProperty("PRIVATE");
String keystore_password = properties.getProperty("PASSWORD");
String key_password = properties.getProperty("PASSWORD");
KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
ks.load(new FileInputStream(path), keystore_password.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey)ks.getKey(alias, key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
// reader and stamper
PdfReader reader = new PdfReader(ORIGINAL);
PdfStamper stamper = PdfStamper.createSignature(reader, new FileOutputStream(dest), '\0');
// appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature("mySig");
appearance.setReason("It's personal.");
appearance.setLocation("Foobar");
if (certified) {
appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
}
if (graphic) {
appearance.setSignatureGraphic(Image.getInstance(RESOURCE));
appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
}
// signature
ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, es, chain, null,null, null, 0, CryptoStandard.CMS);
}
public static void main(String[] args)
throws Exception {
Security.addProvider(new BouncyCastleProvider());
properties.load(new FileInputStream(PATH));
Signaturefield signatures = new Signaturefield();
signatures.createPdf(ORIGINAL);
signatures.signPdf(ORIGINAL, SIGNED1, false, false);
signatures.signPdf(ORIGINAL, SIGNED2, true, true);
}
}
运行后我得到错误:
Exception in thread "main" java.lang.NullPointerException
at java.io.FileInputStream.<init>(FileInputStream.java:134)
at java.io.FileInputStream.<init>(FileInputStream.java:97)
at signaturefield.Signaturefield.signPdf(Signaturefield.java:114)
at signaturefield.Signaturefield.main(Signaturefield.java:146)
Java Result: 1
有修复它的想法吗?多谢