Создайте IExternalSignature с x509Certificate2 в C # и iText 7 - PullRequest
0 голосов
/ 31 мая 2018

Я тестирую библиотеку iText 7.1.2.0 для подписи файлов PDF с использованием цифрового сертификата или смарт-карты (X509Certificate2) в проекте C #.Но я получаю эту ошибку, когда пытаюсь создать IExternalSignature.

enter image description here

Согласно найденной документации ( здесь , здесь и здесь ), способ достижения этого процесса - использовать библиотеку BouncyCastle, которая позволяет извлекать первичные ключи из цифрового сертификата, однако, это дает мне ошибку, и я не могу найти другой способ сделатьЭто.В документации ( здесь ) они создаются из файлов .pfx, но для этого случая мне нужно взять первичные ключи непосредственно из сертификата в кард-ридере.В предыдущих версиях iText было разрешено создание с помощью следующей команды:

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

Но в версии 7 он больше недоступен, и в документации я не вижу, как это сделать.

Кто-то использовал iText 7 и смог подписать, используя X509Certificate2, который знает правильный способ создания IExternalSignature?

Это код, который я использую:

public void SignPDF(string source, string target, X509Certificate2 certificate, string reason, string location, bool addVisibleSign, bool addTimeStamp, string strTSA, int qtySigns, int pageNumber)
    {
        try
        {
            Org.BouncyCastle.X509.X509Certificate vert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate);

            X509CertificateParser objCP = new X509CertificateParser();
            Org.BouncyCastle.X509.X509Certificate[] objChain = new Org.BouncyCastle.X509.X509Certificate[] { objCP.ReadCertificate(certificate.RawData) };

            IList<ICrlClient> crlList = new List<ICrlClient>();
            crlList.Add(new CrlClientOnline(objChain));

            PdfReader objReader = new PdfReader(source);
            PdfSigner objStamper = new PdfSigner(objReader, new FileStream(target, FileMode.Create), false);

            ITSAClient tsaClient = null;
            IOcspClient ocspClient = null;

            if (addTimeStamp)
            {
                OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
                ocspClient = new OcspClientBouncyCastle(ocspVerifier);
                tsaClient = new TSAClientBouncyCastle(strTSA);
            }

            PdfSignatureAppearance signatureAppearance = objStamper.GetSignatureAppearance();
            signatureAppearance.SetReason(reason);
            signatureAppearance.SetLocation(location);
            signatureAppearance.SetPageNumber(pageNumber);
            signatureAppearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);

            if (addVisibleSign && qtySigns == 1)
                signatureAppearance.SetPageRect(new iText.Kernel.Geom.Rectangle(36, 20, 144, 53)).SetPageNumber(pageNumber);
            else if (addVisibleSign && qtySigns == 2)
                signatureAppearance.SetPageRect(new iText.Kernel.Geom.Rectangle(160, 20, 268, 53)).SetPageNumber(pageNumber);
            else if (addVisibleSign && qtySigns == 3)
                signatureAppearance.SetPageRect(new iText.Kernel.Geom.Rectangle(284, 20, 392, 53)).SetPageNumber(pageNumber);
            else if (addVisibleSign && qtySigns == 4)
                signatureAppearance.SetPageRect(new iText.Kernel.Geom.Rectangle(408, 20, 516, 53)).SetPageNumber(pageNumber);

            var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(certificate.PrivateKey).Private;

            IExternalSignature externalSignature = new PrivateKeySignature(pk, "SHA-1");
            objStamper.SignDetached(externalSignature, objChain, crlList, ocspClient, tsaClient, 0, PdfSigner.CryptoStandard.CMS);

            if (objReader != null)
            {
                objReader.Close();
            }
        }
        catch (Exception ex)
        {
            result.error = true;
            result.errorMessage += "Error: " + ex.Message;
        }
    }

Спасибо!

1 Ответ

0 голосов
/ 31 мая 2018

Я не верю, что класс был перенесен в iText 7 - это просто класс-оболочка.

Вы можете увидеть, как создать собственный IExternalSignatureContainer в в этом примере

Обратите внимание, что источник для iText 5 X509Certificate2Signature можно найти здесь

Так что-то вроде этого:

public class X509Certificate2Signature: IExternalSignature {
    private String hashAlgorithm;
    private String encryptionAlgorithm;
    private X509Certificate2 certificate;

    public X509Certificate2Signature(X509Certificate2 certificate, String hashAlgorithm) {
        if (!certificate.HasPrivateKey)
            throw new ArgumentException("No private key.");
        this.certificate = certificate;
        this.hashAlgorithm = DigestAlgorithms.GetDigest(DigestAlgorithms.GetAllowedDigest(hashAlgorithm));
        if (certificate.PrivateKey is RSACryptoServiceProvider)
            encryptionAlgorithm = "RSA";
        else if (certificate.PrivateKey is DSACryptoServiceProvider)
            encryptionAlgorithm = "DSA";
        else
            throw new ArgumentException("Unknown encryption algorithm " + certificate.PrivateKey);
    }

    public virtual byte[] Sign(byte[] message) {
        if (certificate.PrivateKey is RSACryptoServiceProvider) {
            RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) certificate.PrivateKey;
            return rsa.SignData(message, hashAlgorithm);
        }
        else {
            DSACryptoServiceProvider dsa = (DSACryptoServiceProvider) certificate.PrivateKey;
            return dsa.SignData(message);
        }
    }

    public virtual String GetHashAlgorithm() {
        return hashAlgorithm;
    }

    public virtual String GetEncryptionAlgorithm() {
        return encryptionAlgorithm;
    }
}

Будет воспроизводить функцию класса в iText 7. Как использовать класс, показано здесь в моей первой ссылке, хотя выскорее всего, будет использоваться метод signDetached() вместо метода signDeffered().

...