我正在尝试即时签署 PDF。我显然没有这样做。任何帮助表示赞赏。
这只是签署 pdf 的测试。为了以后的目的,我将保存那些私钥和公钥。
目的是动态生成签名 PDF。我按照此链接中显示的代码
以下是代码片段。
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Date;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SignPdf {
Logger logger = LoggerFactory.getLogger(SignPdf.class);
private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;
public byte[] getSignature(byte[] originalBytes, Application oap) throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
KeyPairGenerator generator = KeyPairGenerator.getInstance ("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
generator.initialize (1024, random);
KeyPair keyPair = generator.generateKeyPair();
X509Certificate[] chain =
{
this.getSelfCertificate(
keyPair,
"",
"",
"",
oap.getDateOfApply(),
oap.getDateOfReturn(),
""
)
};
// reader and stamper
PdfReader reader = new PdfReader(originalBytes);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason("REASON");
appearance.setLocation("");
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
appearance.setCrypto(keyPair.getPrivate(), chain, null, PdfSignatureAppearance.SELF_SIGNED);
stamper.close();
return os.toByteArray();
}
private X509Certificate getSelfCertificate(
KeyPair keyPair,
String organisation,
String orgUnit,
String commonName,
Date issueDate,
Date validToDate,
String signatureAlgorithm
){
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
builder.addRDN(BCStyle.OU, orgUnit);
builder.addRDN(BCStyle.O, organisation);
builder.addRDN(BCStyle.CN, commonName);
BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());
X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
builder.build(),
serial,
issueDate,
validToDate,
builder.build(),
keyPair.getPublic()
);
ContentSigner sigGen = new JcaContentSignerBuilder(signatureAlgorithm)
.setProvider(BC)
.build(keyPair.getPrivate());
X509Certificate cert = new JcaX509CertificateConverter()
.setProvider(BC)
.getCertificate(
certGen
.build(sigGen)
);
cert.checkValidity(new Date());
cert.verify(cert.getPublicKey());
return cert;
} catch (Exception e) {
logger.error("{}", e.getMessage());
e.printStackTrace();
}
return null;
}
}
这段代码运行时我无法弄清楚错误。
java.lang.ClassCastException: org.bouncycastle.asn1.ASN1UTCTime incompatible with org.bouncycastle.asn1.ASN1Set
at com.lowagie.text.pdf.PdfPKCS7$X509Name.<init>(PdfPKCS7.java:1724)
at com.lowagie.text.pdf.PdfPKCS7.getSubjectFields(PdfPKCS7.java:1149)
at com.lowagie.text.pdf.PdfSignatureAppearance.getAppearance(PdfSignatureAppearance.java:483)
at com.lowagie.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:1045)
at com.lowagie.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:963)
at com.lowagie.text.pdf.PdfStamper.close(PdfStamper.java:219)
at com.blah.SignPdf.getSignature(SignPdf.java:94) // this is stamper.close();
Maven配置是
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.2.21</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.66</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk15on</artifactId>
<version>1.64</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bctsp-jdk15on</artifactId>
<version>1.46</version>
</dependency>