Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在MemoryStream中创建的iTextSharp符号PDF_C#_Pdf_Itextsharp_Digital Signature - Fatal编程技术网

C# 在MemoryStream中创建的iTextSharp符号PDF

C# 在MemoryStream中创建的iTextSharp符号PDF,c#,pdf,itextsharp,digital-signature,C#,Pdf,Itextsharp,Digital Signature,我需要动态创建一个PDF文件,所以我使用MemoryStream和iTextSharp来编辑PDF。但我想在将PDF文件发送到浏览器之前对其进行数字签名。我在一个示例项目中看到,iTextSharp有一个PDFSigner类,它主要完成所有工作。但正如我所见,它是这样工作的: PDFSigner signer = new PDFSigner(inputFileName, outputFileName, certificate, metaData); signer.Sign(......) 但对

我需要动态创建一个PDF文件,所以我使用MemoryStream和iTextSharp来编辑PDF。但我想在将PDF文件发送到浏览器之前对其进行数字签名。我在一个示例项目中看到,iTextSharp有一个PDFSigner类,它主要完成所有工作。但正如我所见,它是这样工作的:

PDFSigner signer = new PDFSigner(inputFileName, outputFileName, certificate, metaData);
signer.Sign(......)
但对于MemoryStream,我也不能为输入或输出提供物理文件名。我的代码如下:

MemoryStream memoryStream = new MemoryStream();
var document = new Document(iTextSharp.text.PageSize.LETTER, 40, 40, 60, 40);
PdfWriter.GetInstance(document, memoryStream).CloseStream = false;

document.Open();
PopulatePDF(document, someId);
document.Close();

byte[] byteArray = memoryStream.ToArray();

memoryStream.Write(byteArray, 0, byteArray.Length);
memoryStream.Position = 0;

return new FileStreamResult(memoryStream, "application/pdf");

我的问题是,如果PDFSigner只接受字符串-文件名作为参数,我如何使用PDFSigner对象对文档进行签名。

正如Chris Haas所解释的,iText中没有名为
PDFSigner
的类。您可能正在使用非官方版本的iText,在这种情况下,您需要确保正确应用了数字签名

你可以在我写的书中读到更多关于正确数字签名的内容

基本上,这就是使用PKCS#12密钥库进行签名的方式:

Pkcs12Store store = new Pkcs12Store(new FileStream(KEYSTORE, FileMode.Open), PASSWORD);
String alias = "";
ICollection<X509Certificate> chain = new List<X509Certificate>();
// searching for private key
foreach (string al in store.Aliases)
    if (store.IsKeyEntry(al) && store.GetKey(al).Key.IsPrivate) {
        alias = al;
        break;
    }
AsymmetricKeyEntry pk = store.GetKey(alias);
foreach (X509CertificateEntry c in store.GetCertificateChain(alias))
    chain.Add(c.Certificate);
RsaPrivateCrtKeyParameters parameters = pk.Key as RsaPrivateCrtKeyParameters;

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 = "My reason for signing";
appearance.Location = "The middle of nowhere";
appearance.SetVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(parameters, DigestAlgorithms.SHA256);
MakeSignature.SignDetached(appearance, pks, chain, null, null, null, 0, CryptoStandard.CMS);
Pkcs12Store-store=新的Pkcs12Store(新文件流(KEYSTORE,FileMode.Open),密码);
字符串别名=”;
i收集链=新列表();
//搜索私钥
foreach(存储中的字符串al.alias)
if(store.IsKeyEntry(al)和&store.GetKey(al.Key.IsPrivate){
别名=al;
打破
}
AsymmetricKeyEntry pk=store.GetKey(别名);
foreach(X509CertificateEntry c in store.GetCertificateChain(别名))
添加(c.证书);
RsaPrivateCrtKeyParameters=pk.Key作为RsaPrivateCrtKeyParameters;
PdfReader读取器=新PdfReader(src);
FileStream os=新FileStream(dest,FileMode.Create);
PdfStamper stamper=PdfStamper.CreateSignature(读卡器,操作系统,'\0');
//创建外观
PDFSignaturePearance外观=母版。SignaturePearance;
外观.Reason=“我签字的原因”;
外观。位置=“无处可去的中央”;
外观:SetVisibleSignature(新矩形(36748144780),1,“sig”);
//创建签名
IExternalSignature pks=新的PrivateKeySignature(参数,DigestAlgorithms.SHA256);
MakeSignature.signDistached(外观、pks、链、null、null、null、0、CryptoStandard.CMS);
显然,您希望用获取撤销信息甚至允许时间戳的实现来替换
null
值,但这不是您的问题


你的问题是:我能提供一个只存在于内存中的PDF吗?答案是肯定的:创建
PdfReader
实例时的
src
参数可以是指向磁盘上文件的路径,但也可以是从
MemoryStream
获取的
byte[]
,我可能是错的,但我不认为iText实际上有一个名为
PDFSigner
的类,至少我找不到。你是通过在线教程找到这段代码的吗?另外,您使用的是什么版本的iTextSharp?我使用的是iTextSharp 5.5.3,上面的代码来自这个项目:(它使用一个PDFSigner类来工作并进行签名)谢谢。是的,实际上没有正式的PDFSigner类,我发现的项目的作者创建了这个类作为助手,他在其中使用了PdfStamper。第一行的KEYSTORE的输入是什么?@Cerveser它是指向密钥存储的路径,例如
.p12
文件,其中包含一个公钥和私钥对。因为私钥是私有的,所以不能共享。@BrunoLowagie应该读取最后第二行
new PrivateKeySignature(参数,…