iTextSharp - 签名哈希 [英] iTextSharp - Signed Hash

查看:231
本文介绍了iTextSharp - 签名哈希的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 客户端选择要签署的PDF格式

  2. Web服务从pdf中提取哈希并将其发送到外部提供程序

  3. 外部提供程序对哈希进行签名

  4. 外部提供程序发回已签名的哈希

  5. Web服务包括已签名的哈希返回到pdf

  6. 客户端拥有签名PDF

我试图将签名散列插入/更新为pdf时遇到一个大问题。
$ b

我正在使用iTextSharp。



我已经阅读Bruno Lowagie的白皮书PDF文档的数字签名这是一个很大的帮助,但我无法弄清楚如何插入签名散列,顺便说一句,这是我唯一拥有的,没有证书,没有任何东西。



Please,help。

Gabriel

解决方案

根据你的评论,你目前的做法如下:


基本上,我提取pdf文件的哈希像这样。

使用(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())


$ $ $ $ b $ $私人字符串FileHash(byte [] vGblFilePDF) $ b {
vGblHash = Convert.ToBase64String(sha1.ComputeHash(vGblFilePDF));
}
返回vGblHash;
}

然后我将它发送给提供者,形成一个WS,只添加一个Id号码,那么提供者会将我签名的哈希发送给我(签名后),我必须将其插入到pdf中。


这种做法从根本上说是错误的,您已经开始计算错误的哈希值了!

您首先必须准备您的PDF ;在此准备步骤中,您将某些结构添加到PDF中,将PDF标记为包含签名并为稍后插入签名容器预留一部分;所有除了该保留区段之外都将被散列:



(有关某些背景和指向其他文献的信息,请参阅此答案)

此后,必须创建一个具有该文档散列签名的完整PKCS#7 / CMS签名容器并将其插入该保留部分。



这是大多数iText签名代码(这里是Java代码)为您提供的功能:

  PdfReader reader = new PdfReader(src); 
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader,os,'\0');
//创建外观
PdfSignatureAppearance外观= stamper.getSignatureAppearance();
appearance.setReason(原因);
appearance.setLocation(location);
appearance.setVisibleSignature(new Rectangle(36,748,144,780),1,sig);
//创建签名
ExternalDigest digest = new BouncyCastleDigest();
ExternalSignature签名= ...;
MakeSignature.signDetached(外观,摘要,签名,链,null,null,null,0,subfilter);

(取自 C2_01_SignHelloWorld.java 相当于 C2_01_SignHelloWorld.cs

您只需提供与您的提供商进行通信的 ExternalSignature / IExternalSignature 实施方案:

  public interface IExternalSignature {
$ b $ / **
*返回散列算法。
* @返回哈希算法(例如SHA-1,SHA-256,...)
* /
String GetHashAlgorithm();

/ **
*返回用于签名的加密算法。
* @返回加密算法(RSA或DSA)
* /
String GetEncryptionAlgorithm();

/ **
*使用加密算法和
*摘要算法进行签名。
* @param消息你想被哈希和签名的消息
* @返回一个签名的消息摘要
* @throws GeneralSecurityException
* /
byte [] Sign (byte []消息);
}


I'm developing a WebService were a client could sign a PDF, this are the steps:

  1. Client select the pdf to sign
  2. the Web Service Extract the hash from the pdf and send it to an External Provider
  3. the External Provider sign the hash
  4. the External Provider sends back the signed Hash
  5. the Web Service include the signed hash back to the pdf
  6. the Client have the signed PDF

I'd encounter a big problem trying to insert/update the signed hash into the pdf.

I'm using iTextSharp.

I'd already read the white paper "Digital Signatures for PDF documents" from Bruno Lowagie, and it was a great help, but i can't figure it out how to insert the signed hash, wich by the way, is the only thing i have, no certificates, o nothing.

Please, help.

Gabriel

解决方案

According to your comment your current approach is as follows:

Basically I extract the hash of the pdf file like this.

private string FileHash(byte[] vGblFilePDF)
{
    using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
    {
        vGblHash = Convert.ToBase64String(sha1.ComputeHash(vGblFilePDF));
    }
    return vGblHash;
}

then i send it to the provider trought a WS, adding only a Id number, then the provider send me back (after an identification) the signed hash, wich i have to insert into the pdf.

This approach is fundamentally wrong, you already start by calculating the wrong hash!

You first have to prepare your PDF; during this preparation step you add certain structures to the PDF that mark the PDF as containing a signature and reserve a section for the later insertion of a signature container; everything with the exception of that reserved section then is to be hashed:

(For some backgrounds and pointers to additional literature cf. this answer.)

Thereafter a full-blown PKCS#7 / CMS signature container with a signature for that document hash has to be created and inserted in that reserved section.

This is what most of the iText signing code (here in Java) does for you:

PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
// Creating the signature
ExternalDigest digest = new BouncyCastleDigest();
ExternalSignature signature = ...;
MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);

(taken from C2_01_SignHelloWorld.java equivalent to C2_01_SignHelloWorld.cs)

You merely need to provide a ExternalSignature/IExternalSignature implementation communicating with your provider:

public interface IExternalSignature {

    /**
     * Returns the hash algorithm.
     * @return  the hash algorithm (e.g. "SHA-1", "SHA-256,...")
     */
    String GetHashAlgorithm();

    /**
     * Returns the encryption algorithm used for signing.
     * @return the encryption algorithm ("RSA" or "DSA")
     */
    String GetEncryptionAlgorithm();

    /**
     * Signs it using the encryption algorithm in combination with
     * the digest algorithm.
     * @param message   the message you want to be hashed and signed
     * @return  a signed message digest
     * @throws GeneralSecurityException
     */
    byte[] Sign(byte[] message);
} 

这篇关于iTextSharp - 签名哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆