感谢您的帮助,我已经测试了建议的解决方案,但是问题是,当我调用getrangestream()时,会引发NullPointerException。代码如下:
public byte[] presign(string src,string dest){
PdfReader reader=new PdfReader(src);
FileStream os=File.OpenWrite(dest);
PdfStamper stamper =
PdfStamper.CreateSignature(reader, os, '\0');
sap = stamper.SignatureAppearance;
Stream data=sap.GetRangeStream();
hash = DigestAlgorithms.Digest(data, "SHA256");
return hash;
}//returns the hash to signing application on the server
public void postsign(byte[] signed_bytes){
IExternalSignature mysig=new MySignature();
mysig.Sign(signed_bytes);//the signed_hash is returned from the server
MakeSignature.SignDetached(sap,mysig,final_chain,crlList,null,
null,8192,CryptoStandard.CMS)}
/// crllist和final_chain分别是通过读取pem文件生成的“ crl信息”和“证书链”信息
答案 0 :(得分:0)
使用外部签名服务或设备使用iText 5.5.x实现PDF签名的直接方法是使用IExternalSignature
或IExternalSignatureContainer
实现,其中分别使用Sign
方法调用外部签名服务或代码,以使用该设备的自变量对该数据进行签名,并返回结果签名。
为简单起见,我们假设您的签名服务/设备可用于返回完整的CMS签名容器。在这种情况下,可以使用IExternalSignatureContainer
这样的实现:
PdfReader reader = new PdfReader(SRC);
FileStream os = new FileStream(DEST, FileMode.Create);
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.Reason = "For a reason surely";
appearance.Location = "Positively somewhere";
appearance.SetVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
IExternalSignatureContainer externalSignatureContainer = new ExternalServiceContainerSigner();
// Creating the signature
MakeSignature.SignExternalContainer(appearance, externalSignatureContainer, 8192);
使用
class ExternalServiceContainerSigner : IExternalSignatureContainer
{
public void ModifySigningDictionary(PdfDictionary signDic)
{
signDic.Put(PdfName.FILTER, PdfName.ADOBE_PPKLITE);
signDic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_DETACHED);
}
public byte[] Sign(Stream data)
{
String hashAlgorithm = "SHA256";
byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm);
// call your external signature service to create a CMS signature
// container for the given document hash and return the bytes of
// that signature container.
return CALL_YOUR_EXTERNAL_SIGNATURE_SERVICE_TO_CREATE_A_CMS_SIGNATURE_CONTAINER_FOR(hash);
}
}
如果您的签名服务/设备不提供创建CMS签名容器的功能,而是仅提供裸签名字节或PKCS#1样式的签名,则可以
CALL_YOUR_EXTERNAL_SIGNATURE_SERVICE_TO_CREATE_A_CMS_SIGNATURE_CONTAINER_FOR
调用,并使用外部服务/设备为给定文档哈希准备并签名签名容器,或者IExternalSignature
实现来调用您的服务,并使用MakeSignature.SignDetached
使用该实现。