多重签名pdf iText

多重签名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

我试图使用itext 5.5.13.1多次对文档进行签名,模拟不同用户的签名,PdfStamper处于AppendMode模式。如果文档没有签名,则认证级别为CERTIFIED\u NO\u CHANGES\u ALLOWED或CERTIFIED\u FORM\u FILLING\u和\u Annotation,否则我不会将此参数设置为PdfSignatureAppearence。第二次签名后,第一次签名无效,因为文档已更改。有没有办法解决这个问题? 这是我的密码:

        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