Получить неверную подпись из PDF при подписании хэша с помощью закрытого ключа из токена - PullRequest
0 голосов
/ 28 сентября 2019

Я пытаюсь подписать хеш PDF-документа, который я получаю с сервера.Но в Adobe Reader отображается «По крайней мере, одна подпись недействительна».Кто-нибудь может подсказать, что не так в следующем коде.Прямо сейчас я просто попробую реализовать код в одном проекте с отдельным классом.

CODE

prepareHashToken.cs

public class prepareHashToken
{
    public const string OUT_DIR = @"C:\Document\Doc1";

    private class MyExternalSignatureContainer : IExternalSignatureContainer
    {
        protected byte[] sig;

        protected ICollection<X509Certificate> chain;

        public MyExternalSignatureContainer(byte[] sig, ICollection<X509Certificate> chain)
        {
            this.sig = sig;
            this.chain = chain;
        }

        public byte[] Sign(Stream data)
        {
            return sig;
        }
    }

    public byte[] EmptySignature(string src, string dest, IList<X509Certificate> chain)
    {
        PdfReader reader = new PdfReader(src);
        FileStream os = new FileStream(dest, FileMode.Create);
        PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
        PdfSignatureAppearance appearance = stamper.SignatureAppearance;

        AcroFields acro = reader.AcroFields;
        List<string> sig_name = acro.GetSignatureNames();
        string field = "signature_" + (sig_name.Count + 1);
        Console.WriteLine("field : " + field);
        appearance.SetVisibleSignature(new Rectangle(36, 748, 144, 780), 1, field);
        appearance.Certificate = chain[0];
        IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        MakeSignature.SignExternalContainer(appearance, external, 8192);
        Stream inp = appearance.GetRangeStream();
        Sha256Digest digest = new Sha256Digest();
        byte[] hash = DigestAlgorithms.Digest(inp, "SHA256");
        return hash;
    }

    public string createHash(string base64X509, string SRC, string TEMP)
    {
        Directory.CreateDirectory(OUT_DIR);

        byte[] xx = Convert.FromBase64String(base64X509);
        X509.X509Certificate2 x509 = new X509.X509Certificate2(xx);
        X509Certificate m = DotNetUtilities.FromX509Certificate(x509);
        IList<X509Certificate> chain = new List<X509Certificate>();
        chain.Add(m);
        prepareHashToken app = new prepareHashToken();
        byte[] hh = app.EmptySignature(SRC, TEMP, chain);
        string hashString = Convert.ToBase64String(hh);
        return hashString;
    }
}

SignHashToken.cs

public PDFInfo SignPDF(List<string> Hash64, string pinNumber)
{
   using (Session session = slot.OpenSession(false))
   {
     session.Login(CKU.CKU_USER, pin);

     List<ObjectAttribute> privateKeyAttributes = new List<ObjectAttribute>();
     privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
     privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));

     List<ObjectHandle> foundPrivateKeys = session.FindAllObjects(privateKeyAttributes);
     ObjectHandle privateKeyHandle = foundPrivateKeys[0];
     var mechanisms = new Mechanism(CKM.CKM_SHA256_RSA_PKCS);
     byte[] sourceData = Convert.FromBase64String(item);
     byte[] signature = session.Sign(mechanisms, privateKeyHandle, sourceData);
     result = Convert.ToBase64String(signature);
   }
 }

embedSignatureToken.cs

 public class embedSignatureToken
 {
    public const string OUT_DIR = @"C:\Document\Doc1";

    private class MyExternalSignatureContainer : IExternalSignatureContainer
    {
        protected byte[] sig;
        protected ICollection<X509Certificate> chain;

        public MyExternalSignatureContainer(byte[] sig, ICollection<X509Certificate> chain)
        {
            this.sig = sig;
            this.chain = chain;
        }

        public byte[] Sign(Stream data)
        {
            return sig;
        }

        public void ModifySigningDictionary(PdfDictionary signDic) {}
    }

    public void CreateSignature(string src, string dest, byte[] hash, IList<X509Certificate> chain)
    {
        try
        {
            PdfReader reader = new PdfReader(src);
            AcroFields acro = reader.AcroFields;
            List<string> sig_name = acro.GetSignatureNames();
            string field = "signature_" + (sig_name.Count);
            FileStream os = new FileStream(dest, FileMode.Create);
            IExternalSignatureContainer external = new MyExternalSignatureContainer(hash,chain);
            MakeSignature.SignDeferred(reader, field, os, external);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

    public void embedSigned(string base64X509, string hash64, string pin, string SRC, string TEMP, string DEST)
    {
        Directory.CreateDirectory(OUT_DIR);

        byte[] xx = Convert.FromBase64String(base64X509);
        X509.X509Certificate2 x509 = new X509.X509Certificate2(xx);
        X509Certificate m = DotNetUtilities.FromX509Certificate(x509);
        IList<X509Certificate> chain = new List<X509Certificate>();
        chain.Add(m);
        embedSignatureToken app = new embedSignatureToken();

        byte[] hh = Convert.FromBase64String(hash64);

        app.CreateSignature(TEMP, DEST, hh, chain);
    }
}

Base64 предварительной подписи и знака base64 of pre-sign and sign Здесь я положил подписанный PDF

ОБНОВЛЕНИЕ

SignHashToken.cs

   byte[] xx = Convert.FromBase64String(CD.CertData);
   X509Certificate2 x509 = new X509Certificate2(xx);
   X509Certificate m = DotNetUtilities.FromX509Certificate(x509);
   IList<X509Certificate> chain = new List<X509Certificate>();
   chain.Add(m);

   byte[] hash = Convert.FromBase64String(item);
   PrivateKeySignature signature = new PrivateKeySignature(/*Asymmetric key */, "SHA256");
   string hashAlgorithm = signature.GetHashAlgorithm();
   PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false);
   DateTime signingTime = DateTime.Now;
   byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CMS);
   byte[] extSignature = signature.Sign(sh);
   sgn.SetExternalDigest(extSignature, null, signature.GetEncryptionAlgorithm());
   byte[] encod = sgn.GetEncodedPKCS7(hash, tsaClient, null, null, CryptoStandard.CMS);
   result = Convert.ToBase64String(encod);
...