Я пытаюсь подписать хеш 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 предварительной подписи и знака Здесь я положил подписанный 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);