Search code examples
pdfitext

Add sign to PDF using old iText-2.1.7


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


Solution

  • 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())