bcprov-jdk15on-1.55.jar
public static void signPdfByiText(ExternalSignature externalSignature, String pdfFile,String bitmapFilePath, String savePath,int pageIndex, RectF rect,X509Certificate[] chain,List<byte[]>crlBytes,List<byte[]>ocsp, int estimatedSize) throws Exception{
PdfReader reader = new PdfReader(pdfFile);
File file = new File(savePath);
file.delete();
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
PdfStamper pdfStamper = PdfStamper.createSignature(reader, fos, '\0', null, true);
PdfSignatureAppearance sap = pdfStamper.getSignatureAppearance();
sap.setVisibleSignature(new Rectangle(rect.left, rect.top, rect.right, rect.bottom), pageIndex+1, UUID.randomUUID().toString());
if(!TextUtils.isEmpty(bitmapFilePath)){
sap.setSignatureGraphic(com.itextpdf.text.Image.getInstance(bitmapFilePath));
sap.setRenderingMode(RenderingMode.GRAPHIC);
}else{
sap.setRenderingMode(RenderingMode.DESCRIPTION);
}
BouncyCastleDigest externalDigest = new BouncyCastleDigest();
byte[] ocspData = null;
if (estimatedSize == 0) {
estimatedSize = 8192;
if (crlBytes != null) {
for (byte[] element : crlBytes) {
if(element == null){
continue;
}
estimatedSize += element.length + 10;
}
}
if (ocsp != null) {
for (byte[] element : ocsp) {
if(element == null){
continue;
}
estimatedSize += 4192;
ocspData = element;
}
}
}
String displayData = chain[0].getSubjectDN().toString();
sap.setCertificate(chain[0]);
Font font = new Font(BaseFont.createFont(Constant.FONT,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED));
sap.setLayer2Font(font);
sap.setSignatureCreator(StringUtil.getCertDN(displayData, "CN="));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String layer2Text = String.format("%s 签名日期:%s", StringUtil.getCertDN(displayData, "CN="), sdf.format(new Date()));
sap.setLayer2Text(layer2Text);
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE,PdfName.ADBE_PKCS7_SHA1);
dic.setSignatureCreator(sap.getSignatureCreator());
dic.setDate(new PdfDate(sap.getSignDate()));
sap.setCryptoDictionary(dic);
HashMap<PdfName, Integer> exc = new HashMap();
exc.put(PdfName.CONTENTS, new Integer(estimatedSize * 2 + 2));
sap.preClose(exc);
String hashAlgorithm = DigestAlgorithms.SHA1;
PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, null,
externalDigest, true);
InputStream data = sap.getRangeStream();
byte[] hash = DigestAlgorithms.digest(data,
externalDigest.getMessageDigest(hashAlgorithm));
byte[] encodedSig = new byte[0];
if(ocspData==null&&crlBytes==null){
byte[] extSignature = externalSignature.sign(hash);
sgn.setExternalDigest(extSignature, hash,
externalSignature.getEncryptionAlgorithm());
encodedSig = sgn.getEncodedPKCS7(null, null, null,
null, CryptoStandard.CMS);
}else {
byte[] secondDigest = DigestAlgorithms.digest(new ByteArrayInputStream(hash),
externalDigest.getMessageDigest(hashAlgorithm));
byte[] sh = sgn.getAuthenticatedAttributeBytes(secondDigest, ocspData, crlBytes,
CryptoStandard.CMS);
byte[] extSignature = externalSignature.sign(sh);
sgn.setExternalDigest(extSignature, hash,
externalSignature.getEncryptionAlgorithm());
encodedSig = sgn.getEncodedPKCS7(secondDigest, null, ocspData,
crlBytes, CryptoStandard.CMS);
}
if (estimatedSize < encodedSig.length) {
throw new IOException("Not enough space");
}
byte[] paddedSig = new byte[estimatedSize];
System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);
PdfDictionary dic2 = new PdfDictionary();
dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
sap.close(dic2);
}