Create IExternalSignature with x509Certificate2 in C# and iText 7

。_饼干妹妹 提交于 2020-06-22 01:43:05

问题


I am testing the iText 7.1.2.0 library to sign pdf files, using a digital certificate or smart card (X509Certificate2) in a C # project. But I'm getting this error when I try to create the IExternalSignature.

enter image description here

According to the documentation found (here, here and here), the way to achieve this process is using the BouncyCastle library that allows extracting the primary keys from the digital certificate, however, it is giving me an error and I can not find another way to do it. In the documentation (here) they are created from .pfx files, but for this case, I need to take the primary keys directly from the certificate in the card reader. In previous versions of iText, it's allowed the creation with the following command:

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

But in version 7 it is no longer available and in the documentation I do not see how to do it.

Someone has used iText 7 and has been able to sign using an X509Certificate2 that knows the correct way to create the IExternalSignature?

This is the code that I am using:

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;
        }
    }

Thanks!


回答1:


I do not believe that class was ported to iText 7- it is just a wrapper class.

You can see how to create a custom IExternalSignatureContainer in this example

Note that the source for the iText 5 X509Certificate2Signature can be found here

So something like this:

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;
    }
}

Will replicate the class' function in iText 7. How to use the class is shown here in my first link, though you most likely will be using the signDetached() method instead of the signDeffered() method.



来源:https://stackoverflow.com/questions/50627483/create-iexternalsignature-with-x509certificate2-in-c-sharp-and-itext-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!