I've been working on a digital signature function for some days, now that I have everything working it is time to try to print the stamp in all pages but I'm not doing great...
Trying to give a quick resume, to show the stamp what I do is creating PdfStamper, PdfSignatureAppearance and a Rectangle, then call the
appearance.setVisibleSignature(rectangle, 1, "SIGNATURE")
The second parameter "1" above is the page number that I want to show the stamp, it is okay to be 1 by now, as I tried to do in order to show stamp in other page was creating other instances of PdfStamper, PdfSignatureAppearance and a Rectangle but set it to page 2. If it had worked I would have put it within a loop and keep changing the page parameter.
But why didn't it work??? Well, near the end I call a method of MakeSignature and among the parameters I have to pass one of the appearences I created, if I call it more than once the signature appears only on the page related to the last appearence I pass to it.
For example:
MakeSignature.signDetached(appearance2, digest, pks, chain, null, null, null, 0, CryptoStandard.CMS);
MakeSignature.signDetached(appearance, digest, pks, chain, null, null, null, 0, CryptoStandard.CMS);
The stamp will be showed on the first page only.
Maybe I could get some help here???
Here it goes the whole thing:
public String signPdfFirstTime(String src, String dest, PrivateKey pk, Certificate[] chain, String providerName, String conteudoBase64, X509Certificate cert, String alias) throws IOException, DocumentException, GeneralSecurityException
{
byte[] conteudoBinario = Base64.decode(conteudoBase64);
FileOutputStream fos = new FileOutputStream(path + File.separator + src);
fos.write(conteudoBinario);
fos.close();
File f = new File(path + File.separator + src);
FileInputStream in = new FileInputStream(f);
PdfReader reader = new PdfReader(in);
int qtypages = reader.getNumberOfPages();
FileOutputStream os = new FileOutputStream(path + File.separator + dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
Rectangle rectangle = new Rectangle(550, 50, 610, 500);// funciona vertical
appearance.setVisibleSignature(rectangle, 1, "SIGNATURE");
//Here I build a custom message...nothing relevant
StringBuilder stampMessage = new StringBuilder();
stampMessage.append("...");
stampMessage.append(alias);
stampMessage.append(" - ");
// customize appearance layer 2 to display text vertically
PdfTemplate layer2 = appearance.getLayer(2);
layer2.transform(new AffineTransform(0, 1, -1, 0, rectangle.getWidth(), 0));
Font font = new Font();
font.setColor(BaseColor.BLACK);
ColumnText ct2 = new ColumnText(layer2);
ct2.setRunDirection(PdfWriter.RUN_DIRECTION_NO_BIDI);
ct2.setSimpleColumn(new Phrase(stampMessage.toString(), font), 0, 0, rectangle.getHeight(), rectangle.getWidth(), 15, Element.ALIGN_LEFT);
ct2.go();
appearance.setCertificate(cert);
//Here starts where I tried to make a second stamp to show in the page 2
FileOutputStream fos2 = new FileOutputStream(path + File.separator + src);
fos2.write(conteudoBinario);
fos2.close();
File f2 = new File(path + File.separator + src);
FileInputStream in2 = new FileInputStream(f2);
PdfReader reader2 = new PdfReader(in2);
FileOutputStream os2 = new FileOutputStream(path + File.separator + dest);
PdfStamper stamper2 = PdfStamper.createSignature(reader2, os2, '\0');
// Creating the appearance
PdfSignatureAppearance appearance2 = stamper2.getSignatureAppearance();
Rectangle rectangle2 = new Rectangle(550, 50, 610, 500);// funciona vertical
appearance2.setVisibleSignature(rectangle2, 3, "ASSINATURA2");
//Cria a msg que aparece na estampa
StringBuilder stampMessage2 = new StringBuilder();
stampMessage2.append(" - ");
PdfTemplate layer22 = appearance.getLayer(2);
layer22.transform(new AffineTransform(0, 1, -1, 0, rectangle2.getWidth(), 0));
Font font2 = new Font();
font2.setColor(BaseColor.BLACK);
ColumnText ct22 = new ColumnText(layer22);
ct22.setRunDirection(PdfWriter.RUN_DIRECTION_NO_BIDI);
ct22.setSimpleColumn(new Phrase(stampMessage2.toString(), font2), 0, 0, rectangle2.getHeight(), rectangle2.getWidth(), 15, Element.ALIGN_LEFT);
ct22.go();
appearance2.setCertificate(cert);
// Creating the signature
ExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, providerName);
ExternalDigest digest = new BouncyCastleDigest();
List<CrlClient> crlList = new ArrayList<CrlClient>();
crlList.add(new CrlClientOnline());
LtvVerification v = stamper.getLtvVerification();
LtvVerification v2 = stamper2.getLtvVerification();
OcspClient ocspClient = new OcspClientBouncyCastle();
String url = CertificateUtil.getCRLURL(cert);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509CRL crl = (X509CRL) cf.generateCRL(new URL(url).openStream());
System.out.println("CRL valid until: " + crl.getNextUpdate());
System.out.println("Certificate revoked: " + crl.isRevoked(chain[0]));
if (crl.isRevoked(chain[0])) {
throw new GeneralSecurityException("CERTIFICADO REVOGADO!");
}
else {
MakeSignature.processCrl(cert, crlList);
MakeSignature.signDetached(appearance2, digest, pks, chain, null, null, null, 0, CryptoStandard.CMS);
MakeSignature.signDetached(appearance, digest, pks, chain, null, null, null, 0, CryptoStandard.CMS);
os.close();
byte[] b = this.read(f);
return Base64.encodeBytes(b);
}
}