I'm working on a legacy project that uses the old iText-2.1.7 library. I'm just starting to figure it out and I won't be upgrading to a more modern version yet, so I need help with this version specifically. I need add signature to pdf, here is my code:
def postProcessPdf(pdf: Array[Byte], os: OutputStream): Unit = {
val reader = new PdfReader(pdf)
Security.addProvider(new KalkanProvider)
val stamper = PdfStamper.createSignature(reader, os, '\u0000')
val appearance = stamper.getSignatureAppearance
val signDate = Calendar.getInstance
val pdfSignature = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED)
pdfSignature.setDate(new PdfDate(signDate))
pdfSignature.setCert(CryptUtils.cert.getEncoded)
appearance.setCryptoDictionary(pdfSignature)
appearance.setCrypto(null, CryptUtils.chain, null, PdfSignatureAppearance.WINCER_SIGNED)
appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED)
val estimatedSize = 8192
val exc = new HashMap[PdfName, Int]()
exc.put(PdfName.CONTENTS, estimatedSize * 2 + 2)
appearance.preClose(exc)
val data = appearance.getRangeStream()
val sgn = new PdfPKCS7(null, CryptUtils.chain, null, "SHA256", null, false)
val digest = MessageDigest.getInstance("SHA256","KALKAN")
val dataBytes = IOUtils.toByteArray(data)
digest.update(dataBytes)
val appeareanceHash = digest.digest()
val hashToSign = sgn.getAuthenticatedAttributeBytes(appeareanceHash, appearance.getSignDate(), null)
val signature = Signature.getInstance("SHA256withRSA","KALKAN")
signature.initSign(CryptUtils.privateKey)
signature.update(hashToSign)
val signedHash = signature.sign()
sgn.setExternalDigest(signedHash,null,"RSA")
val encodedPKCS7 = sgn.getEncodedPKCS7(signedHash, appearance.getSignDate())
val paddedSig = new Array[Byte](estimatedSize)
System.arraycopy(encodedPKCS7, 0, paddedSig, 0, encodedPKCS7.length)
val dic = new PdfDictionary()
dic.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true))
appearance.close(dic)
}
Result in Adobe Acrobat Reader: image Error: Document has been altered or corrupted since it was signed. What is mean and what i supposed to do? Thank you in advance. PDF-file: link
You have to use the same parameter values for the matching parameters of your sgn.getAuthenticatedAttributeBytes
and sgn.getEncodedPKCS7
calls.
In your code you have:
val hashToSign = sgn.getAuthenticatedAttributeBytes(appeareanceHash, appearance.getSignDate(), null)
...
sgn.setExternalDigest(signedHash,null,"RSA")
val encodedPKCS7 = sgn.getEncodedPKCS7(signedHash, appearance.getSignDate())
but it should be
val hashToSign = sgn.getAuthenticatedAttributeBytes(appeareanceHash, appearance.getSignDate(), null)
...
sgn.setExternalDigest(signedHash,null,"RSA")
val encodedPKCS7 = sgn.getEncodedPKCS7(appeareanceHash, appearance.getSignDate())