我正在开发一个使用旧 iText-2.1.7 库的旧项目。我刚刚开始弄清楚,我还不会升级到更现代的版本,所以我特别需要这个版本的帮助。 我需要在 pdf 中添加签名,这是我的代码:
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)
}
Adobe Acrobat Reader 中的结果: 图像 错误:文档自签名以来已被更改或损坏。什么是意思以及我应该做什么?先感谢您。 PDF 文件:链接
您必须对
sgn.getAuthenticatedAttributeBytes
和 sgn.getEncodedPKCS7
调用的匹配参数使用相同的参数值。
在您的代码中您有:
val hashToSign = sgn.getAuthenticatedAttributeBytes(appeareanceHash, appearance.getSignDate(), null)
...
sgn.setExternalDigest(signedHash,null,"RSA")
val encodedPKCS7 = sgn.getEncodedPKCS7(signedHash, appearance.getSignDate())
但应该是这样
val hashToSign = sgn.getAuthenticatedAttributeBytes(appeareanceHash, appearance.getSignDate(), null)
...
sgn.setExternalDigest(signedHash,null,"RSA")
val encodedPKCS7 = sgn.getEncodedPKCS7(appeareanceHash, appearance.getSignDate())