Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Security.Cryptography.X509Certificates;
- using System.Collections.Generic;
- using System.Security.Cryptography;
- using System.Security;
- #if PDF_SIGNATURE_ENABLED
- namespace Simple35.Pdf
- {
- using iTextSharp.text.pdf;
- using System.IO;
- using Org.BouncyCastle.X509;
- using System.Security.Cryptography.Pkcs;
- using CryptoPro.Sharpei;
- /// <summary>
- /// Для сборки примера необходимо установить последнюю версию iTextSharp и определить переменную PDF_SIGNATURE_ENABLED
- /// </summary>
- public class Sign
- {
- [STAThread]
- public static int Main(string[] args)
- {
- // Разбираем аргументы
- if (args.Length < 2)
- {
- Console.WriteLine("Pdf.Sign <document> <certificate-dn> [<key-container-password>]");
- return 1;
- }
- string document = args[0];
- string certificate_dn = args[1];
- // Находим секретный ключ по сертификату в хранилище MY
- X509Store store = new X509Store("My", StoreLocation.CurrentUser);
- store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
- X509Certificate2Collection found = store.Certificates.Find(
- X509FindType.FindBySubjectName, certificate_dn, true);
- if (found.Count == 0)
- {
- Console.WriteLine("Секретный ключ не найден.");
- return 1;
- }
- if (found.Count > 1)
- {
- Console.WriteLine("Найдено более одного секретного ключа.");
- return 1;
- }
- X509Certificate2 certificate = found[0];
- if (args.Length > 2)
- {
- //set password.
- Gost3410CryptoServiceProvider cert_key = certificate.PrivateKey as Gost3410CryptoServiceProvider;
- if (null != cert_key)
- {
- var cspParameters = new CspParameters();
- //копируем параметры csp из исходного контекста сертификата
- cspParameters.KeyContainerName = cert_key.CspKeyContainerInfo.KeyContainerName;
- cspParameters.ProviderType = cert_key.CspKeyContainerInfo.ProviderType;
- cspParameters.ProviderName = cert_key.CspKeyContainerInfo.ProviderName;
- cspParameters.Flags = cert_key.CspKeyContainerInfo.MachineKeyStore
- ? (CspProviderFlags.UseExistingKey|CspProviderFlags.UseMachineKeyStore)
- : (CspProviderFlags.UseExistingKey);
- cspParameters.KeyPassword = new SecureString();
- foreach (var c in args[2])
- {
- cspParameters.KeyPassword.AppendChar(c);
- }
- //создаем новый контекст сертификат, поскольку исходный открыт readonly
- certificate = new X509Certificate2(certificate.RawData);
- //задаем криптопровайдер с установленным паролем
- certificate.PrivateKey = new Gost3410CryptoServiceProvider(cspParameters);
- }
- }
- PdfReader reader = new PdfReader(document);
- PdfStamper st = PdfStamper.CreateSignature(reader, new FileStream(document + "_signed.pdf", FileMode.Create, FileAccess.Write), '\0');
- PdfSignatureAppearance sap = st.SignatureAppearance;
- // Загружаем сертификат в объект iTextSharp
- X509CertificateParser parser = new X509CertificateParser();
- Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] {
- parser.ReadCertificate(certificate.RawData)
- };
- sap.SetCrypto(null, chain, null, null);
- sap.Reason = "I like to sign";
- sap.Location = "Universe";
- sap.Acro6Layers = true;
- sap.Render = PdfSignatureAppearance.SignatureRender.NameAndDescription;
- sap.SignDate = DateTime.Now;
- // Выбираем подходящий тип фильтра
- PdfName filterName = new PdfName("CryptoPro PDF");
- // Создаем подпись
- PdfSignature dic = new PdfSignature(filterName, PdfName.ADBE_PKCS7_DETACHED);
- dic.Date = new PdfDate(sap.SignDate);
- dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN");
- 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.RangeStream;
- 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);
- Console.WriteLine("Документ {0} успешно подписан на ключе {1} => {2}.",
- document, certificate.Subject, document + "_signed.pdf");
- return 0;
- }
- }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment