전자 서명을 기존 PDF에 추가하는 데 필요한 개념 증명 데모를 작성하고 있습니다. 나는 내가 얻지 못하는 이상한 문제를 겪고있다. 일부 문서에 서명을 추가하면 다른 문서에 서명을 추가해도 작동하지 않으며 Adobe Reader에서 열 수없는 손상된 파일이 생성되는 것 같습니다. 기존 PDF 문서에 서명 할 때 종종 손상된 파일이 발생합니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iText;
using iText.Kernel.Pdf;
using System.IO;
using iText.Layout;
using iText.Layout.Element;
using iText.Kernel.Geom;
using Org.BouncyCastle.Crypto.Tls;
using iText.Signatures;
using System.Collections.ObjectModel;
using Org.BouncyCastle.Pkcs;
using System.Security.Cryptography.X509Certificates;
using Org.BouncyCastle.Crypto;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using iText.IO.Image;
namespace LTVSkilrikjaDemo
{
class Program
{
static void Main(string[] args)
{
string welcomeText = "Welcome to LTVSkilríkjaDemotolid!";
string pressEnterToTry = "Commands: 's' - sign, 'stop' - stops the programme";
Console.WriteLine(welcomeText);
Console.WriteLine(pressEnterToTry);
// Base directory prepared
string basedir = AppDomain.CurrentDomain.BaseDirectory;
int index = basedir.IndexOf(@"bin\");
basedir = basedir.Remove(index);
string readString = Console.ReadLine().ToLower();
while(!readString.Equals("stop"))
{
if(readString.Equals("c"))
{
string inFile = "Infile2.pdf";
string outFile = "Outfile2.pdf";
// Open PDF document and decide where to write the new document
PdfWorker worker = new PdfWorker();
worker.ReadPdf(basedir + "App_Data\\InFiles\\" + inFile, basedir + "App_Data\\OutFiles\\" + outFile);
// Start working on certificate
X509Store store = new X509Store("My");
store.Open(OpenFlags.ReadOnly);
Collection<Org.BouncyCastle.X509.X509Certificate> xcertificates = new Collection<Org.BouncyCastle.X509.X509Certificate>();
foreach (X509Certificate2 mCert in store.Certificates)
{
if (mCert.Subject.IndexOf("CN=Róbert") > -1)
{
xcertificates.Add(Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(mCert));
}
}
Org.BouncyCastle.X509.X509Certificate[] certificatesProcessed = new Org.BouncyCastle.X509.X509Certificate[xcertificates.Count];
for(int i = 0; i < xcertificates.Count; i++)
{
certificatesProcessed[i] = xcertificates[i];
}
var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(store.Certificates[5].PrivateKey).Private;
try
{
worker.Sign(certificatesProcessed, pk, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CADES, "No apparent raisin!", "Lost in Iceland", null, null, null, 0, true, basedir);
}
catch(Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error! " + ex.Message + "\n\r" + ex.StackTrace);
if(ex.InnerException != null)
{
Console.WriteLine("Inner exception: " + ex.InnerException.Message);
}
Console.ForegroundColor = ConsoleColor.Gray;
}
}
else if(!readString.Equals("stop"))
{
Console.WriteLine("Command not understood. Understand only 's' and 'stop'.");
}
readString = Console.ReadLine();
}
Console.WriteLine("Goodbye!");
System.Threading.Thread.Sleep(500);
}
}
public class PdfWorker
{
private PdfDocument _document;
private string _source;
private string _dest;
public void ReadPdf(string source, string dest)
{
_source = source;
_dest = dest;
}
public void Sign(Org.BouncyCastle.X509.X509Certificate[] chain, Org.BouncyCastle.Crypto.ICipherParameters pk,
string digestAlgorithm, PdfSigner.CryptoStandard subfilter, string reason,
string location, Collection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
int estimatedSize, bool initial, string baseDir)
{
File.Copy(_source, _dest, true);
FileStream f = new FileStream(_dest, FileMode.Append);
try
{
PdfSigner signer = new PdfSigner(new PdfReader(_source), f, true);
_document = signer.GetDocument();
_document.AddNewPage();
// Work the last page
Rectangle pageSize = _document.GetLastPage().GetPageSizeWithRotation();
//PdfWriter w = _document.GetWriter();
//long currentPos = w.GetCurrentPos();
float llx = pageSize.GetWidth() - 350 - 20; //pageSize.GetWidth()/2 - 350/2;
float lly = pageSize.GetHeight() - 50 - 20; // pageSize.GetHeight()/2 - 150/2;
float urx = 350; //llx + 350;
float ury = 50; //lly + 150;
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
appearance.SetPageRect(new Rectangle(llx, lly, urx, ury));
appearance.SetReason(reason);
appearance.SetLocation(location);
byte[] imagebytes = File.ReadAllBytes(baseDir + "App_Data\\UndirskriftDemo.png");
// It is not possible to use the path as it contains Icelandic characters
// which itext chokes on. We use byte array instead
ImageData imgData = ImageDataFactory.Create(imagebytes);
Image img = new Image(imgData);
img = img.ScaleToFit(350.0f, 50.0f);
appearance.SetImage(imgData);
int pageCount = _document.GetNumberOfPages();
// Creating the appearance
if(initial == true)
{
signer.SetCertificationLevel(PdfSigner.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
}
appearance.SetPageNumber(pageCount);
Rectangle rect = new Rectangle(10, 50, 350, 50);
appearance.SetPageRect(rect).SetPageNumber(pageCount);
appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);
signer.SetFieldName(signer.GetNewSigFieldName());
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
signer.SignDetached(pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
Console.WriteLine("Signing successful!");
}
catch(Exception ex)
{
throw ex;
}
finally
{
_document.Close();
f.Close();
}
}
}
}
여기에 다음 문서를 참조하십시오
여기 내 코드입니다. Infile1.pdf 서명 할 수는 없지만 Infile2.pdf는 서명이 잘되어 있습니다. Outfile1.pdf는 손상된 파일입니다. https://app.box.com/s/52jqe8qirl80km6hunxucs00dntx70o5
이 원인은 무엇입니까? 입력 PDF 파일이나 위의 프로그램에 대해 뭔가 있습니까?
File.Copy (...)로 줄 주석 처리를 시도했지만 출력 파일을 열려고 할 때 여전히 동일한 오류가 발생합니다. 파일을 복사 한 이유는 원본 파일이 변경 되었기 때문에 내가 원하지 않는 것으로 생각하기 때문입니다. 또한 나는 임시 파일을 만들고 싶지 않았고 마침내 최종 문서가 내가 본 한 예에서 완성 된 것처럼 마침내 완성되었다. – rbadi76
* 출력 파일을 열려고해도 동일한 오류가 발생합니다. * - 해당 파일도 공유하십시오. 다른 이유로 동일한 오류가 표시 될 수 있습니다. – mkl
@ rbadi76 아, 한 가지 추가 사항은'FileStream'을'FileMode.Append'로 열지 마십시오 :'PdfSigner' 출력을 아무 것도 추가하지 않으려는 것입니다. ... – mkl