Подпишите PDF с помощью iTextSharp 5.3.3 и USB-токена

Я новичок в iTextSharp (и StackOverFlow). Я'я пытаюсь подписать PDF в C # с помощью внешнего USB-токена. Я пытаюсь использовать следующий код, который явыкопал из интернета.

Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();

//Get Sertifiacte
X509Certificate2 certClient = null;
X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
st.Open(OpenFlags.MaxAllowed);
X509Certificate2Collection collection = X509Certificate2UI.SelectFromCollection(st.Certificates, "Please choose certificate:", "", X509SelectionFlag.SingleSelection);
if (collection.Count > 0){
   certClient = collection[0];
}
st.Close();
//Get Cert Chain
IList chain = new List();
X509Chain x509chain = new X509Chain();
x509chain.Build(certClient );
foreach (X509ChainElement x509ChainElement in x509chain.ChainElements){
    chain.Add(DotNetUtilities.FromX509Certificate(x509ChainElement.Certificate));
}

PdfReader reader = new PdfReader(sourceDocument);
FileStream resStream = new FileStream(resultDocument, FileMode.Create, FileAccess.ReadWrite);

PdfStamper stamper = PdfStamper.CreateSignature(reader, resStream , '\0', null, true);

PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.Reason = reason;
appearance.Location = location;
appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(20, 10, 170, 60), 1, "Signed");

X509Certificate2Signature es = new X509Certificate2Signature(certClient, "SHA-1");
MakeSignature.SignDetached(appearance, es, chain, null, null, null, 0, CryptoStandard.CMS);

Проблема в том, что я получаю исключение:

System.Security.Cryptography.CryptographicException was unhandled
  Message=Invalid type specified.

  Source=mscorlib
  StackTrace:
       at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
       at System.Security.Cryptography.Utils._GetKeyParameter(SafeKeyHandle hKey, UInt32 paramID)
       at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
       at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
       at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
       at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
       at iTextSharp.text.pdf.security.X509Certificate2Signature..ctor(X509Certificate2 certificate, String hashAlgorithm)
       at WindowsFormsApplication1.PDFSignerHelper.signPdfFile(String sourceDocument, String resultDocument, X509Certificate2 certClient, String reason, String location)
  InnerException: 
 Kaloyan Iliev09 нояб. 2012 г., 15:54
Итак, сейчас я вернусь к iTextSharp 5.2.1 и буду использовать примеры изitextpdf.sourceforge.net/howtosign.html#signextdic, Они делают эту работу за меня. Если кто-то найдет решение для iTextSHarp 5.3.3, я буду рад его увидеть.

Ответы на вопрос(3)

который может подписать PDF из магазина Windows, SmartCard или файла Pfx / P12. Может быть, это может быть полезно вам четыре

using System;
using System.Windows.Forms;
using System.IO;

using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;



namespace SignPdf
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private  SecureString GetSecurePin(string PinCode)
        {
            SecureString pwd = new SecureString();
            foreach (var c in PinCode.ToCharArray()) pwd.AppendChar(c);
            return pwd;
        }
        private  void button1_Click(object sender, EventArgs e)
        {
            //Sign from SmartCard
            //note : ProviderName and KeyContainerName can be found with the dos command : CertUtil -ScInfo
            string ProviderName = textBox2.Text;
            string KeyContainerName = textBox3.Text;
            string PinCode = textBox4.Text;
            if (PinCode != "")
            {
                //if pin code is set then no windows form will popup to ask it
                SecureString pwd = GetSecurePin(PinCode);
                CspParameters csp = new CspParameters(1,
                                                        ProviderName,
                                                        KeyContainerName,
                                                        new System.Security.AccessControl.CryptoKeySecurity(),
                                                        pwd);
                try
                {
                    RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp);
                    // the pin code will be cached for next access to the smart card
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Crypto error: " + ex.Message);
                    return;
                }
            }           
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2 cert = null;
            if ((ProviderName == "") || (KeyContainerName == ""))
            {
                MessageBox.Show("You must set Provider Name and Key Container Name");
                return;
            }
            foreach (X509Certificate2 cert2 in store.Certificates)
            {
                if (cert2.HasPrivateKey)
                {
                    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert2.PrivateKey;
                    if (rsa == null) continue; // not smart card cert again
                    if (rsa.CspKeyContainerInfo.HardwareDevice) // sure - smartcard
                    {
                        if ((rsa.CspKeyContainerInfo.KeyContainerName == KeyContainerName) && (rsa.CspKeyContainerInfo.ProviderName == ProviderName))
                        {
                            //we find it
                            cert = cert2;
                            break;
                        }
                    }
                }
            }
            if (cert == null)
            {
                MessageBox.Show("Certificate not found");
                return;
            }
            SignWithThisCert(cert);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //Sign with certificate selection in the windows certificate store
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2 cert = null;
            //manually chose the certificate in the store
            X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(store.Certificates, null, null, X509SelectionFlag.SingleSelection);
            if (sel.Count > 0)
                cert = sel[0];
            else
            {
                MessageBox.Show("Certificate not found");
                return;
            }
            SignWithThisCert(cert);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //Sign from certificate in a pfx or a p12 file
            string PfxFileName = textBox5.Text;
            string PfxPassword = textBox6.Text;
            X509Certificate2 cert = new X509Certificate2(PfxFileName, PfxPassword);
            SignWithThisCert(cert);
        }

        private void SignWithThisCert(X509Certificate2 cert)
        {
            string SourcePdfFileName = textBox1.Text;
            string DestPdfFileName = textBox1.Text + "-Signed.pdf";
            Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
            Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(cert.RawData) };
            IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");
            PdfReader pdfReader = new PdfReader(SourcePdfFileName);
            FileStream signedPdf = new FileStream(DestPdfFileName, FileMode.Create);  //the output pdf file
            PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
            PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
            //here set signatureAppearance at your will
            signatureAppearance.Reason = "Because I can";
            signatureAppearance.Location = "My location";
            signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
            MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
            //MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CADES);
            MessageBox.Show("Done");
        }

    }


}
 Tejasvi Hegde20 авг. 2015 г., 15:23
Очень хорошо написаны методы и ответ.
 Jorge Rocha08 февр. 2019 г., 18:56
Очень хорошо, спасибо
 Kaloyan Iliev08 мая 2014 г., 15:24
Спасибо, Жан-Люк. Я закончил с моим проектом, но я буду иметь в виду ваш код в будущем развитии.
 Elizabeth Dimova11 февр. 2019 г., 16:51
Кажется, это работает, но в результате подпись не действительна. Я использую смарт-карту, защищенную PIN-кодом, с неэкспортируемым закрытым ключом - PKCS # 12. Спасибо
 jonatanes20 апр. 2019 г., 16:52
Привет. Большое спасибо за пример. Но то же самое с токеном USB? то есть я могу применить его, подписав с сертификатом, который находится в USB-токене?

что и выше, но использует файл сертификата вместо хранилища для подписи документа PDF на последней странице.

 X509Certificate2 cert = new X509Certificate2("C:\\mycert.p12");

 Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
 Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] {
 cp.ReadCertificate(cert.RawData)};

 IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");

 PdfReader pdfReader = new PdfReader("C:\\multi-page-pdf.pdf");

 var signedPdf = new FileStream("C:\\multi-page-pdf-signed.pdf", FileMode.Create);

 var pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
 PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;

 signatureAppearance.SignatureGraphic = Image.GetInstance("C:\\logo.png");
 signatureAppearance.Reason = "Because I can";
 signatureAppearance.Location = "My location";
 signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 250, 150), pdfReader.NumberOfPages, "Signa,ture");
 signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;

 MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);

Копируйте, вставляйте, импортируйте необходимые библиотеки и работайте над чем-то другим.

Решение Вопроса

смарт-карту и USB-токен (производитель -www.author.kiev.ua):

            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(store.Certificates, null, null, X509SelectionFlag.SingleSelection);

            X509Certificate2 cert = sel[0];

            Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
            Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] {
            cp.ReadCertificate(cert.RawData)};

            IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");

            PdfReader pdfReader = new PdfReader(pathToBasePdf);

            signedPdf = new FileStream(pathToBasePdf, FileMode.Create);

            pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
            PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;

            signatureAppearance.SignatureGraphic = Image.GetInstance(pathToSignatureImage);
            signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 250, 150), pdfReader.NumberOfPages, "Signature");
            signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;

            MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
 user217335322 янв. 2016 г., 14:51
Не берите в голову. Кажется, в какой-то момент Acrobat импортировал сертификаты в мой местный магазин и оттуда просматривал их. К USB-токену сейчас действительно нет доступа .. Что-то не так с моим промежуточным ПО / драйвером ... Как эти компании продают эти вещи? Я'мы провели дни в поисках правильных версий драйверов ... :(
 Sasha21 мая 2017 г., 22:10
@ user2173353 в нашем случае мы неникаких проблем) примеры, драйверы, поддержка) благодаря производству
 user217335322 янв. 2016 г., 13:01
Есть ли какие-либо случаи сертификатов от подключенных USB-токенов, не указаны при использовании этого способа? Потому что мой знакСертификат s не указан в этом коде, пока Acrobatделает перечислите это. Хотя Акробат сообщает "Набор ключей не определен. " ошибка при попытке подписать с ним ...

Ваш ответ на вопрос