我已经完成了所有类似的问题,但找不到应用itextsharp延迟签名的情况。
基本上,我的应用程序使用由远程Web服务创建的PKCS#7
签名来签署pdf文档。
我的应用程序向此Web服务发送原始文档的哈希值(添加空签名字段后的可签名字节的哈希),并接收Base64编码的签名文件。
我将此签名嵌入到先前生成的具有空签名字段的临时pdf文件中。
最后,我的签名未经过验证,因为Adobe Reader说文档已更改或已损坏。
添加空签名字段并获取Pdf的可签名字节的代码
public static string GetBytesToSign(string unsignedPdf, string tempPdf, string signatureFieldName)
{
if (File.Exists(tempPdf))
File.Delete(tempPdf);
using (PdfReader reader = new PdfReader(unsignedPdf))
{
using (FileStream os = File.OpenWrite(tempPdf))
{
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(36, 748, 250, 400), 1, signatureFieldName);
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.SignExternalContainer(appearance, external, 8192);
byte[] array = SHA256Managed.Create().ComputeHash(appearance.GetRangeStream());
return Convert.ToBase64String(array);
}
}
}
由于此操作生成tempPdf
,我从此tempPdf
文件接收pdf文档的可签名字节的哈希值。
然后使用下面的代码,我重新打开这个tempFile并嵌入了Base64编码的PKCS#7
签名。
打开Temp Pdf并嵌入收到的签名的代码
public static void EmbedSignature(string tempPdf, string signedPdf, string signatureFieldName, string signature)
{
byte[] signedBytes = Convert.FromBase64String(signature);
using (PdfReader reader = new PdfReader(tempPdf))
{
using (FileStream os = File.OpenWrite(signedPdf))
{
IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes);
MakeSignature.SignDeferred(reader, signatureFieldName, os, external);
}
}
}
作为此操作的结果,我的最终signedPdf
已生成。但是,Adobe表示签名因更改或损坏而无效。
Temporary File Generated For Signing
我发送给网络服务的tempFile文件的哈希是:
z9qIyvtp4cRBZ1SSCQ + P0JVRinz5lvjYjXk3L7YP / IE =
我从网络服务收到的签名是:
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
我比较了tempFile和signedFile的字节,只有tempFile的零(我认为用于临时签名文件)被signedFile中的实际签名替换。
我真的被困在这一点上。我不知道接下来我应该在哪里看。
答案 0 :(得分:1)
在您从网络服务收到的签名中有:
39 59: . . . SEQUENCE {
41 9: . . . . OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
: . . . . . (PKCS #7)
52 46: . . . . [0] {
54 44: . . . . . OCTET STRING
: . . . . . . 7A 39 71 49 79 76 74 70 z9qIyvtp
: . . . . . . 34 63 52 42 5A 31 53 53 4cRBZ1SS
: . . . . . . 43 51 2B 50 30 4A 56 52 CQ+P0JVR
: . . . . . . 69 6E 7A 35 6C 76 6A 59 inz5lvjY
: . . . . . . 6A 58 6B 33 4C 37 59 50 jXk3L7YP
: . . . . . . 2F 49 45 3D /IE=
: . . . . . }
: . . . . }
[...]
1955 9: . . . . . SEQUENCE {
1957 5: . . . . . . OBJECT IDENTIFIER sha1 (1 3 14 3 2 26)
: . . . . . . . (OIW)
1964 0: . . . . . . NULL
: . . . . . . }
1966 93: . . . . . [0] {
1968 24: . . . . . . SEQUENCE {
1970 9: . . . . . . . OBJECT IDENTIFIER contentType (1 2 840 113549 1 9 3)
: . . . . . . . . (PKCS #9)
1981 11: . . . . . . . SET {
1983 9: . . . . . . . . OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
: . . . . . . . . . (PKCS #7)
: . . . . . . . . }
: . . . . . . . }
1994 28: . . . . . . SEQUENCE {
1996 9: . . . . . . . OBJECT IDENTIFIER signingTime (1 2 840 113549 1 9 5)
: . . . . . . . . (PKCS #9)
2007 15: . . . . . . . SET {
2009 13: . . . . . . . . UTCTime 22/09/2017 13:18:38 GMT
: . . . . . . . . }
: . . . . . . . }
2024 35: . . . . . . SEQUENCE {
2026 9: . . . . . . . OBJECT IDENTIFIER messageDigest (1 2 840 113549 1 9 4)
: . . . . . . . . (PKCS #9)
2037 22: . . . . . . . SET {
2039 20: . . . . . . . . OCTET STRING
: . . . . . . . . . EF 37 38 3B B1 31 AB 96 .78;.1..
: . . . . . . . . . CE FC 47 1E 32 A7 79 73 ..G.2.ys
: . . . . . . . . . 5D 95 15 04 ]...
: . . . . . . . . }
: . . . . . . . }
: . . . . . . }
2061 13: . . . . . SEQUENCE {
2063 9: . . . . . . OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
: . . . . . . . (PKCS #1)
2074 0: . . . . . . NULL
: . . . . . . }
此处,您的base64编码哈希显示为嵌入式签名数据(偏移量56..99)。此外,散列算法被选择为“SHA-1”(偏移1955..1965),并且签名文档散列是20字节值,其匹配SHA-1散列值的大小。另外,RSA用于签名,如PKCS#1 1.5(偏移2061..2075)中所述。
因此,看起来您的签名服务不会将您的输入用作base64编码的预先计算的文档哈希值,而是使用SHA1withRSA / 2048作为明文数据进行签名。
因此错误不在您的iText中使用代码,而在您的签名服务调用代码中。