多重签名pdf iText
我试图使用itext 5.5.13.1多次对文档进行签名,模拟不同用户的签名,PdfStamper处于AppendMode模式。如果文档没有签名,则认证级别为CERTIFIED\u NO\u CHANGES\u ALLOWED或CERTIFIED\u FORM\u FILLING\u和\u Annotation,否则我不会将此参数设置为PdfSignatureAppearence。第二次签名后,第一次签名无效,因为文档已更改。有没有办法解决这个问题? 这是我的密码:多重签名pdf iText,itext,Itext,我试图使用itext 5.5.13.1多次对文档进行签名,模拟不同用户的签名,PdfStamper处于AppendMode模式。如果文档没有签名,则认证级别为CERTIFIED\u NO\u CHANGES\u ALLOWED或CERTIFIED\u FORM\u FILLING\u和\u Annotation,否则我不会将此参数设置为PdfSignatureAppearence。第二次签名后,第一次签名无效,因为文档已更改。有没有办法解决这个问题? 这是我的密码: public
public void Sign(string Thumbprint, string document, string logoPath) {
X509Certificate2 certificate = FindCertificate(Thumbprint);
PdfReader reader = new PdfReader(document);
//Append mode
PdfStamper st = PdfStamper.CreateSignature(reader, new FileStream(SignedDocumentPath(document), FileMode.Create, FileAccess.Write), '\0', null, true);
int signatureWidth = 250;
int signatureHeight = 100;
int NewXPos = 0;
int NewYPos = 0;
SetStampCoordinates(reader, st, ref NewXPos, ref NewYPos, signatureWidth, signatureHeight);
PdfSignatureAppearance sap = st.SignatureAppearance;
if (reader.AcroFields.GetSignatureNames().Count == 0)
{
SetSignatureFieldOptions(certificate, sap, reader, "1", 1, NewXPos, NewYPos, signatureWidth, signatureHeight);
}
else {
SetSignatureFieldOptions(certificate, sap, reader, "2", NewXPos, NewYPos, signatureWidth, signatureHeight);
}
Image image = Image.GetInstance(logoPath);
image.ScaleAbsolute(50, 50);
Font font1 = SetFont("TIMES.TTF", BaseColor.BLUE, 10, 0);
Font font2 = SetFont("TIMES.TTF", BaseColor.BLUE, 8, 0);
PdfTemplate layer = sap.GetLayer(2);
Chunk chunk1 = new Chunk($"\r\nДОКУМЕНТ ПОДПИСАН\r\nЭЛЕКТРОННОЙ ПОДПИСЬЮ\r\n", font1);
Chunk chunk2 = new Chunk($"Сертификат {certificate.Thumbprint}\r\n" +
$"Владелец {certificate.GetNameInfo(X509NameType.SimpleName, false)}\r\n" +
$"Действителен с {Convert.ToDateTime(certificate.GetEffectiveDateString()).Date.ToShortDateString()} " +
$"по {Convert.ToDateTime(certificate.GetExpirationDateString()).Date.ToShortDateString()}\r\n", font2);
PdfTemplate layer0 = sap.GetLayer(0);
image.SetAbsolutePosition(5, 50);
layer0.AddImage(image);
Paragraph para1 = SetParagraphOptions(chunk1, 1, 50, 0, 2, 1.1f);
Paragraph para2 = SetParagraphOptions(chunk2, 0, 5, 15, 0.5f, 1.1f);
ColumnText ct = new ColumnText(layer);
ct.SetSimpleColumn(3f, 3f, layer.BoundingBox.Width - 3f, layer.BoundingBox.Height);
ct.AddElement(para1);
ct.AddElement(para2);
ct.Go();
layer.SetLineWidth(3);
layer.SetRGBColorStroke(0, 0, 255);
layer.Rectangle(0, 0, layer.BoundingBox.Right, layer.BoundingBox.Top);
layer.Stroke();
EncryptDocument(certificate, sap);
}
public X509Certificate2 FindCertificate(string Thumbprint) {
X509Store store = new X509Store("My", StoreLocation.CurrentUser);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
X509Certificate2Collection found = store.Certificates.Find(
X509FindType.FindByThumbprint, Thumbprint, true);
X509Certificate2 certificate = found[0];
if (certificate.PrivateKey is Gost3410_2012_256CryptoServiceProvider cert_key)
{
var cspParameters = new CspParameters
{
KeyContainerName = cert_key.CspKeyContainerInfo.KeyContainerName,
ProviderType = cert_key.CspKeyContainerInfo.ProviderType,
ProviderName = cert_key.CspKeyContainerInfo.ProviderName,
Flags = cert_key.CspKeyContainerInfo.MachineKeyStore
? (CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore)
: (CspProviderFlags.UseExistingKey),
KeyPassword = new SecureString()
};
certificate = new X509Certificate2(certificate.RawData)
{
PrivateKey = new Gost3410_2012_256CryptoServiceProvider(cspParameters)
};
}
return certificate;
}
public Font SetFont(string TTFFontName, BaseColor color, float size, int style) {
string ttf = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), TTFFontName);
BaseFont baseFont = BaseFont.CreateFont(ttf, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
Font font = new Font(baseFont, size, style);
font.Color = color;
return font;
}
public Paragraph SetParagraphOptions(Chunk chunk, int ParagraphAligment, float marginLeft, float marginTop, float fixedLeading, float multipledLeading) {
Paragraph paragraph = new Paragraph();
paragraph.Alignment = ParagraphAligment;
paragraph.IndentationLeft = marginLeft;
paragraph.SpacingBefore = marginTop;
paragraph.SetLeading(fixedLeading, multipledLeading);
paragraph.Add(chunk);
return paragraph;
}
public string SignedDocumentPath(string document) {
string filename = String.Concat(Path.GetFileNameWithoutExtension(document), "_signed.pdf");
string path = Path.Combine(Path.GetDirectoryName(document), filename);
return path;
}
public void SetSignatureFieldOptions(X509Certificate2 certificate, PdfSignatureAppearance sap, PdfReader reader, string field, int level, int XPos, int YPos, int width, int height)
{
X509CertificateParser parser = new X509CertificateParser();
try
{
Rectangle rectangle = new Rectangle(XPos, YPos, XPos + width, YPos + height);
sap.SetVisibleSignature(rectangle, reader.NumberOfPages, field);
sap.Certificate = parser.ReadCertificate(certificate.RawData);
sap.Reason = "I agree";
sap.Location = "Location";
sap.Acro6Layers = true;
sap.SignDate = DateTime.Now;
sap.CertificationLevel = level;
}
catch (Exception ex)
{
if (ex.Message == $"The field {certificate.Thumbprint} already exists.")
throw new Exception("Вы уже подписали данный документ");
}
}
public void SetSignatureFieldOptions(X509Certificate2 certificate, PdfSignatureAppearance sap, PdfReader reader,string field, int XPos, int YPos, int width, int height) {
X509CertificateParser parser = new X509CertificateParser();
try
{
Rectangle rectangle = new Rectangle(XPos, YPos, XPos + width, YPos + height);
sap.SetVisibleSignature(rectangle, reader.NumberOfPages, field);
sap.Certificate = parser.ReadCertificate(certificate.RawData);
sap.Reason = "I agree";
sap.Location = "Location";
sap.Acro6Layers = true;
sap.SignDate = DateTime.Now;
}
catch (Exception ex) {
if (ex.Message == $"The field {certificate.Thumbprint} already exists.")
throw new Exception("Вы уже подписали данный документ");
}
}
public void EncryptDocument(X509Certificate2 certificate, PdfSignatureAppearance sap) {
PdfName filterName;
if (certificate.PrivateKey is Gost3410CryptoServiceProvider)
filterName = new PdfName("CryptoPro#20PDF");
else
filterName = PdfName.ADOBE_PPKLITE;
PdfSignature dic = new PdfSignature(filterName, PdfName.ADBE_PKCS7_DETACHED);
dic.Date = new PdfDate(sap.SignDate);
dic.Name = certificate.GetNameInfo(X509NameType.SimpleName, false);
if (sap.Reason != null)
dic.Reason = sap.Reason;
if (sap.Location != null)
dic.Location = sap.Location;
sap.CryptoDictionary = dic;
int intCSize = 4000;
Dictionary<PdfName, int> hashtable = new Dictionary<PdfName, int>();
hashtable[PdfName.CONTENTS] = intCSize * 2 + 2;
sap.PreClose(hashtable);
Stream s = sap.GetRangeStream();
MemoryStream ss = new MemoryStream();
int read = 0;
byte[] buff = new byte[8192];
while ((read = s.Read(buff, 0, 8192)) > 0)
{
ss.Write(buff, 0, read);
}
ContentInfo contentInfo = new ContentInfo(ss.ToArray());
SignedCms signedCms = new SignedCms(contentInfo, true);
CmsSigner cmsSigner = new CmsSigner(certificate);
signedCms.ComputeSignature(cmsSigner, false);
byte[] pk = signedCms.Encode();
byte[] outc = new byte[intCSize];
PdfDictionary dic2 = new PdfDictionary();
Array.Copy(pk, 0, outc, 0, pk.Length);
dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true));
sap.Close(dic2);
}
public void符号(字符串指纹、字符串文档、字符串logoPath){
X509Certificate2证书=FindCertificate(指纹);
PdfReader reader=新的PdfReader(文档);
//附加模式
PdfStamper st=PdfStamper.CreateSignature(读取器,新文件流(SignedDocumentPath(document),FileMode.Create,FileAccess.Write),'\0',null,true);
int signatureWidth=250;
int signatureHeight=100;
int NewXPos=0;
int NewYPos=0;
设置标记坐标(读卡器、st、ref NewXPos、ref NewYPos、签名宽度、签名高度);
PDFSignaturePearance sap=st.SignaturePearance;
if(reader.AcroFields.GetSignatureNames().Count==0)
{
设置SignatureFieldOptions(证书、sap、读卡器、“1”、1、NewXPos、NewYPos、signatureWidth、signatureHeight);
}
否则{
设置SignatureFieldOptions(证书、sap、读卡器、“2”、新XPOS、新ypOS、signatureWidth、signatureHeight);
}
Image=Image.GetInstance(logoPath);
可缩放溶质(50,50);
Font font1=SetFont(“TIMES.TTF”,BaseColor.BLUE,10,0);
Font font2=SetFont(“TIMES.TTF”,BaseColor.BLUE,8,0);
PdfTemplate layer=sap.GetLayer(2);
Chunk chunk1=新块($“\r\nБСССАППППППППСАПСССЮ\r\nПЛБППППППППСЮ\r\n”,font1);
Chunk chunk2=新块($“ССцццааа{certificate.Thumbprint}\r\n”+
$“Саааааа{certificate.GetNameInfo(X509NameType.SimpleName,false)}\r\n”+
$“СцццццццСц{Convert.ToDateTime(certificate.GetEffectiveDateString()).Date.toSortDateString()}”+
$“Пö{Convert.ToDateTime(certificate.GetExpirationDateString()).Date.ToSortDateString()}\r\n”,font2);
PdfTemplate layer0=sap.GetLayer(0);
图像。设置绝对位置(5,50);
图层0.添加图像(图像);
段落para1=设置段落选项(chunk1、1、50、0、2、1.1f);
段落para2=设置段落选项(chunk2、0、5、15、0.5f、1.1f);
ColumnText ct=新的ColumnText(图层);
ct.SetSimpleColumn(3f,3f,layer.BoundingBox.Width-3f,layer.BoundingBox.Height);
ct.补充元素(para1);
ct.补充元素(para2);
ct.Go();
层。设置线宽(3);
layer.SetRGBColorStroke(0,0,255);
矩形(0,0,layer.BoundingBox.Right,layer.BoundingBox.Top);
层笔划();
加密文件(证书、sap);
}
公共X509Certificate2 FindCertificate(字符串指纹){
X509Store store=新的X509Store(“我的”,StoreLocation.CurrentUser);
store.Open(OpenFlags.openingonly | OpenFlags.ReadOnly);
X509Certificate2Collection-found=store.Certificates.Find(
X509FindType.FindByThumbprint,指纹,true);
X509Certificate2证书=找到[0];
if(certificate.PrivateKey是Gost3410_2012_256CryptoServiceProvider证书密钥)
{
var cspParameters=新的cspParameters
{
KeyContainerName=cert_key.CspKeyContainerInfo.KeyContainerName,
ProviderType=cert_key.CspKeyContainerInfo.ProviderType,
ProviderName=cert_key.CspKeyContainerInfo.ProviderName,
Flags=cert_key.CspKeyContainerInfo.MachineKeyStore
?(CSProviderFlags.UseExistingKey | CSProviderFlags.UseMachineKeyStore)
:(CSProviderFlags.UseExistingKey),
KeyPassword=newsecurestring()
};
证书=新的X509Certificate2(certificate.RawData)
{
PrivateKey=新Gost3410_2012_256CryptoServiceProvider(CSPTParameters)
};
}
退货证明;
}
公共字体SetFont(字符串TTFFontName、基色颜色、浮点大小、int样式){
字符串ttf=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts),TTFFontName);
BaseFont BaseFont=BaseFont.CreateFont(ttf,BaseFont.IDENTITY\u H,BaseFont.NOT\u EMBEDDED);
Font Font=新字体(基本字体、大小、样式);
font.Color=颜色;
返回字体;
}
公共段落SetParagraphOptions(块块、整型段落对齐、浮点marginLeft、浮点marginTop、浮点固定前导、浮点倍数前导){
段落=新段落();
段落对齐=段落对齐;
段落.缩进左侧=边缘左侧;
段落.SpacingBefore=marginTop;
段落.设置引导(固定引导、多重引导);
添加(段);
返回段;
}
公共字符串签名文档路径(字符串文档){
string filename=string.Concat(Path.GetFileNameWithoutExtension(document),“\u signed.pdf”);
字符串path=path.Combine(path.GetDirectoryName(文档),文件名);
返回路径;
}
public void SetSignatureFieldOptions(X509Certificate2证书、PdfSignatureAppearance sap、PdfReader读取器、字符串字段、int-level、int-XPos、int-YPos、int-width、int-height)
{
X509CertificateParser=新的X509CertificateParser();
尝试
{
矩形矩形=新矩形(XPos、YPos、XPos+宽度、YPos+高度);
sap.SetVisibleSignature(矩形,reader.NumberOfPages,字段);
sap认证
q
Q
q
Q