我关注以下帖子:iTextSharp-如何获取PDF内容进行签名,然后在以后进行签名,作为从PDF文档获取数据的基础,创建一个带有空白签名的临时文件,然后返回该临时文件的哈希值。散列被发送到在本地拥有令牌的客户端,在那里对其进行签名,并返回到签名的web应用程序。此时,我将其转换为字节并生成最终的签名文档。
但是,签名的文档没有有效的签名,显示消息:Error in decoding BER。
1)生成临时文件的代码,添加空白签名并返回Base64编码哈希:
Public Shared Function GetBytesToSign(ByVal unsignedPdf As String, ByVal tempPdf As String, ByVal signatureFieldName As String) As String
Using reader As PdfReader = New PdfReader(unsignedPdf)
Using os As FileStream = File.OpenWrite(tempPdf)
Dim stamper As PdfStamper = PdfStamper.CreateSignature(reader, os, vbNullChar)
Dim appearance As PdfSignatureAppearance = stamper.SignatureAppearance
appearance.SetVisibleSignature(New Rectangle(36, 748, 144, 780), 1, signatureFieldName)
Dim external As IExternalSignatureContainer = New ExternalBlankSignatureContainer(PdfName.ADBE_PKCS7_DETACHED, PdfName.ADBE_PKCS7_SHA1)
MakeSignature.SignExternalContainer(appearance, external, 8192)
Dim Hash As Byte() = SHA256.Create().ComputeHash(appearance.GetRangeStream())
Dim Base64 As String = Convert.ToBase64String(Hash)
Return Base64
End Using
End Using
End Function
3)我接收签名哈希并将其转换为字节,生成最终的签名文件:
Public Shared Sub EmbedSignature(ByVal tempPdf As String, ByVal signedPdf As String, ByVal signatureFieldName As String, ByVal signedBytes As Byte())
Using reader As PdfReader = New PdfReader(tempPdf)
Using os As FileStream = File.Create(signedPdf)
Dim external As IExternalSignatureContainer = New MyExternalSignatureContainer(signedBytes)
MakeSignature.SignDeferred(reader, signatureFieldName, os, external)
End Using
End Using
End Sub
Partial Class MyExternalSignatureContainer
Implements IExternalSignatureContainer
Private ReadOnly signedBytes As Byte()
Public Sub New(ByVal signedBytes As Byte())
Me.signedBytes = signedBytes
End Sub
Public Function Sign(data As Stream) As Byte() Implements IExternalSignatureContainer.Sign
Return signedBytes
'Throw New NotImplementedException()
End Function
Public Sub ModifySigningDictionary(signDic As PdfDictionary) Implements IExternalSignatureContainer.ModifySigningDictionary
Throw New NotImplementedException()
End Sub
End Class
签名PDF
mkl,谢谢你回来
Public Function GetBytesToSignNew(ByVal unsignedPdf As String, ByVal tempPdf As String, ByVal signatureFieldName As String, ByVal certificateChain As Org.BouncyCastle.X509.X509Certificate()) As Byte()
' we create a reader and a stamper
Dim reader As PdfReader = New PdfReader(unsignedPdf)
Dim baos As FileStream = File.OpenWrite(tempPdf)
Dim chain = certificateChain
Dim pdfStamper As PdfStamper = PdfStamper.CreateSignature(reader, baos, Microsoft.VisualBasic.ChrW(92), Nothing, True)
Dim sap As PdfSignatureAppearance = pdfStamper.SignatureAppearance
sap.Certificate = certificateChain(0)
sap.SetVisibleSignature(New iTextSharp.text.Rectangle(36, 720, 160, 780), 1, signatureFieldName)
'sap.SetVisibleSignature(signatureFieldName);
sap.SignDate = DateTime.Now
Dim dic As PdfSignature = New PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED)
dic.Date = New PdfDate(sap.SignDate)
dic.Name = CertificateInfo.GetSubjectFields(chain(0)).GetField("CN")
sap.CryptoDictionary = dic
sap.Certificate = certificateChain(0)
sap.Acro6Layers = True
sap.Reason = "test"
sap.Location = "test"
Dim external As IExternalSignatureContainer = New ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED)
MakeSignature.SignExternalContainer(sap, external, 8192)
Dim signatureContainer As PdfPKCS7 = New PdfPKCS7(Nothing, chain, "SHA256", False)
Dim hash() As Byte = DigestAlgorithms.Digest(sap.GetRangeStream, "SHA256")
PDFHash.Text = Convert.ToBase64String(hash)
Session("signatureContainer") = signatureContainer
Return hash
End Function
Private Sub Sign21032020(signatureContainer As PdfPKCS7, ByVal certificateChain As Org.BouncyCastle.X509.X509Certificate(), signedBytes As Byte(), tmpPdf As String, signedPdf As String, signatureFieldName As String) As Byte
Try
Using reader As PdfReader = New PdfReader(tmpPdf)
Using outputStream As FileStream = File.OpenWrite(signedPdf)
Dim external As IExternalSignatureContainer = New MyExternalSignatureContainer(signedBytes, certificateChain, signatureContainer)
MakeSignature.SignDeferred(reader, signatureFieldName, outputStream, external)
End Using
End Using
' Return New Byte()
Catch ex As Exception
File.Delete(tmpPdf)
Console.WriteLine("Error signing file: " + ex.Message)
End Try
End Sub
从客户端返回的签名哈希:
DU7KOJKQS8/7+O00TE7F/IYZCZRIWLTXAOWAADJWK2SSZYNAR1FXB4ANOIMLQE3XKR680EGDG5ORJGD4IIU4GDCM0LGIRTO/+YFWZ+RALL6PUSW8ZKI3UKTCNGXGAI3UUDGGHMV/KNFXKNNOVD5JUAVSSL3H6CLJQV8/KNB2VFCPM7R5K4ZIYXM7LTVKJ98OWS7D7ServP6FJTCMIJFTQ6IVEF6V5MJPFRZZX43ETKOU
temppdf:
Temppdf
SignedPDF:
罗伯托·皮雷斯
这里的主要问题是,您只是简单地将客户端返回的签名字节嵌入到PDF中,而不需要进一步的ado。
但是,由于您在子筛选器中的签名声称是adbe.pkcs7.sha1签名,您需要嵌入一个PKCS#7/CMS签名容器,而这不是您的客户端返回的。
在这里,您切换到在签名子过滤器中声明adbe.pkcs7.detached。这也要求您嵌入一个PKCS#7/CMS签名容器,而且这也比使用adbe.pkcs7.SHA1更可取,后者使用SHA1(一个被认为已经不够安全的摘要算法),在PDF上下文中,它甚至被证明是不安全的。
此外,您现在嵌入了一个PKCS#7/CMS签名容器。因此,Adobe Reader现在可以解码嵌入式签名(在解码BER时不再出错)。
但是您错误地生成了签名容器:
virtual public byte[] getAuthenticatedAttributeBytes(byte[] secondDigest, byte[] ocsp, ICollection<byte[]> crlBytes, CryptoStandard sigtype)
(在这里,seconddigest
参数必须包含PDF范围流的哈希值。)
消化字节数组,
让你的客户签下这个哈希,
virtual public void SetExternalDigest(byte[] digest, byte[] RSAdata, String digestEncryptionAlgorithm)
使用pdfpkcs7
对象的以下方法完成CMS签名容器:
virtual public byte[] GetEncodedPKCS7(byte[] secondDigest, ITSAClient tsaClient, byte[] ocsp, ICollection<byte[]> crlBytes, CryptoStandard sigtype)
(这里的seconddigest
、ocsp
、crlbytes
和sigtype
的值必须与GetAuthenticatedattributeBytes
调用中的值相同。)
最后使用Makesignature.SignDeferred
和适当的IExternalSignatureContainer
实现将这些字节嵌入到PDF中。
我正在开发一个客户机-服务器应用程序,其中客户机必须使用他们的签名签署PDF文档,并将它们上传到服务器。由于客户端没有将签名嵌入PDF的手段,他们只能读取原始字节并以原始字节的形式生成签名,因此任务变得复杂。 我正在尝试实现以下工作流: 客户端将未签名的PDF上载到服务器 服务器打开PDF,提取客户端需要签名的字节,并将这些字节发送回 客户端接收这些字节,使用客户端证书对其进行签名,并将签名发送到
问题内容: 如何在iText中完成此操作?我有一个带有客户签名的PDF。我需要向未签名的属性添加ocsp响应。 我知道如何使用 但我不知道如何使用替换PDF 。如果我使用此代码: 包含签名的字典在哪里,则签名(在Adobe Reader中打开文档时)被破坏。 问题答案: 当iText 在正常模式下操作文档时,它可以(并且经常)重新排列现有的PDF对象。显然,这破坏了任何现有集成签名的哈希值。此外,
我有一个关于计算PDF文档摘要以用于数字签名的快速问题(与我前面的一个问题有点相关,我试图弄清楚为什么您需要知道客户的证书以创建正确的摘要)。在Adobe关于PDF格式的文档中,指定了以下内容: 字节范围摘要应在文件中的一个字节范围内计算,该范围应由签名字典中的字节范围条目指示。这个范围应该是整个文件,包括签名字典,但不包括签名值本身(内容条目)。 因此,在这一点上,事情似乎相当简单,只需消化除/
印度的《公司法》有一些变化。其中值得注意的是,有一项规定,如果公司进行了数字签名,则可以以电子形式维护其登记册。以下几点让我感到困惑: > 记录一旦以数字方式标注日期和签名,不得编辑或更改; 记录应能够根据法案的规定或根据法案制定的规则进行更新,更新日期应能够记录在每次更新中。 想象一下,我们正在对PDF中的表进行数字签名。如果表中最初有2行,并且用户对pdf进行数字签名。现在,我们在pdf中再添
我有一个场景,我需要用iText7库从pdf中获取签名信息。签名可能存在,也可能不存在。当我为没有任何数字签名的PDF实例化一个新的对象时,会出现异常 “没有相关的PdfWriter用于进行间接操作。” .如果有签名,就很好用。我不确定如何纠正这个异常。 更新为包含代码示例
我正在编写一个服务,其中我用一个空容器预签名pdf文件,从pdf文件中提取一个字节范围的散列,并将其发送到另一个服务,这将允许用户使用移动电话对散列进行签名。我拿回一个证书,我将注入到预签名pdf文件中的签名容器中。 签名本身起作用,数字签名是有效的,但我只需要更改可见签名本身的文本。我认为这是可能的,因为可见签名实际上与证书本身没有任何关系,所以显示来自证书的名称只是一种方便,特别是在多个签名的