public void sign()
{
Org.BouncyCastle.X509.X509CertificateParser cp = new
Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new
Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate
(this.getCertificate().RawData) };
bool bHasPrivateKey;
bHasPrivateKey = this.getCertificate().HasPrivateKey;
if (!bHasPrivateKey)
{
MessageBox.Show("El certificado seleccionado no es
válido para firmar digitalmente.");
return;
}
PdfReader reader = new PdfReader(this.getOriginalFileName
());
FileStream signedFileStream = new FileStream
(this.getSignedFileName(), FileMode.Create);
PdfStamper stp = PdfStamper.CreateSignature(reader,
signedFileStream, '\0', null, true);
sap = stp.SignatureAppearance;
appearanceHandler.setAppearanceStyleTo(sap,
appearanceStyle, new System.Drawing.Rectangle(100, 100, 200, 300));
sap.SetCrypto(null, chain, null, null);
sap.Location = PdfPKCS7.GetSubjectFields(chain[0]).GetField
("L");
sap.Contact = this.contactInfo;
sap.Reason = this.getReason();
sap.Acro6Layers = true;
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS,
PdfName.ADBE_PKCS7_SHA1);
dic.Date = new PdfDate(sap.SignDate);
dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField
("CN");
if (sap.Reason != null)
dic.Reason = sap.Reason;
if (appearanceHandler.showLocation)
dic.Location = sap.Location;
if (appearanceHandler.showContact)
dic.Contact = sap.Contact;
sap.CryptoDictionary = dic;
int csize = 15000;
Hashtable exc = new Hashtable();
exc[PdfName.CONTENTS] = csize * 2 + 2;
sap.PreClose(exc);
try
{
RSACryptoServiceProvider rsa =
(RSACryptoServiceProvider) this.certificate.PrivateKey;
SHA1Managed sha = new SHA1Managed();
byte[] hashedData = sha.ComputeHash(sap.RangeStream);
byte[] sig = rsa.SignHash(hashedData,
CryptoConfig.MapNameToOID("SHA1"));
bool verified = rsa.VerifyHash(hashedData, "SHA1",
sig);
MessageBox.Show("Verified: " + verified);
byte[] outc = new byte[csize];
PdfDictionary dic2 = new PdfDictionary();
Array.Copy(sig, 0, outc, 0, sig.Length);
dic2.Put(PdfName.CONTENTS, new PdfString
(outc).SetHexWriting(true));
sap.Close(dic2);
signedFileStream.Close();
}
catch (CryptographicException ce)
{
MessageBox.Show(ce.Message);
}
}
I iterate the sign method one time for each pdf file.
I use a private CSP instead the Microsoft Base CSP, because i need to
do a massive signature of files, when i tried to do that with the
Microsoft CSP, the application hangs and throws a Cryptographic
Exception, the only way that i found to get it works, was to use the
CSP provided by the token manufacturer.
When i used the Microsoft CSP with CMSSigner, everything, except the
massive signature, went well... when i signed a single pdf file, the
signature was verified correct by adobe reader. But now with this
code, using the Safenet CSP,the massive signature work fine but all
signatures are verified wrong... the message that acrobat reader
throws is: "Error decoding BER:".
I do not know what can i do for solve this. Any Ideas on what could be
happen?,
Thanks in advance,
Juan Manuel Diaz
Acrobat is very sensitive to ASN.1 formatting and it's elements and the only
meaningful message it can give is "invalid BER encoding" or "Error decoding
BER" (different message in different versions).
Try using PDFBlackbox ( http://www.eldos.com/sbb/net-pdf.php ), it produces
correctly accepted signatures and works with both custom CSPs and PKCS#11
drivers.
--
With best regards,
Eugene Mayevski
http://www.eldos.com/ - security and virtual storage components
Thanks Eugene, i will try it!!, its free?,
Regards,
JM Diaz