image in pdf file becomes invisible after adding digital signature - c#

I am using iTextSharp library for digital signature. In my PDF file having a QR code and once we applied signature the QR code became a gray color.
The figure (A) shows a original PDF and figure (B) shows the PDF file after digital signature.
following is the code to apply the signature. Please help me, why the QR code became gray color.
public void Sign(PDFSignatureAP sigAP, bool encrypt, PdfEncryption Enc)
{
PdfReader reader = new PdfReader(this.inputPDF);
reader.RemoveUsageRights();
PdfStamper st;
if (this.myCert == null) //No signature just write meta-data and quit
{
st = new PdfStamper(reader, new FileStream(this.outputPDF,
FileMode.Create,FileAccess.Write));
}
else
{
st = PdfStamper.CreateSignature(reader, new FileStream(this.outputPDF, FileMode.Create,
FileAccess.Write), '\0', null, sigAP.Multi);
}
if (encrypt && Enc != null) Enc.Encrypt(st);
st.MoreInfo = this.metadata.getMetaData();
st.XmpMetadata = this.metadata.getStreamedMetaData();
if (this.myCert == null) //No signature just write meta-data and quit
{
st.Close();
return;
}
var pass = new SecureString();
char[] array = myCert.Password.ToCharArray();
foreach (char ch in array)
{
pass.AppendChar(ch);
}
var privateKey = myCert.SCertificate.PrivateKey as RSACryptoServiceProvider;
CspParameters cspParameters = new CspParameters(privateKey.CspKeyContainerInfo.ProviderType,
privateKey.CspKeyContainerInfo.ProviderName,
privateKey.CspKeyContainerInfo.KeyContainerName,
new System.Security.AccessControl.CryptoKeySecurity(),
pass);
RSACryptoServiceProvider rsaCsp;
if (string.IsNullOrEmpty(myCert.Path))
rsaCsp = new RSACryptoServiceProvider(cspParameters);
PdfSignatureAppearance sap = st.SignatureAppearance;
sap.Reason = sigAP.SigReason;
sap.Contact = sigAP.SigContact;
sap.Location = sigAP.SigLocation;
if (sigAP.Visible)
{
iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page);
sap.Image = sigAP.RawData == null ? null :
iTextSharp.text.Image.GetInstance(sigAP.RawData);
if(!string.IsNullOrEmpty(sigAP.CustomText))
sap.Layer2Text = sigAP.CustomText + Environment.NewLine + "Date :" + DateTime.Now;
sap.Acro6Layers = false;
sap.Layer4Text = PdfSignatureAppearance.questionMark;
sap.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
sap.SetVisibleSignature(new iTextSharp.text.Rectangle(sigAP.SigX, sigAP.SigY, sigAP.SigX + sigAP.SigW, sigAP.SigY + sigAP.SigH), sigAP.Page, "Signature");
}
IExternalSignature externalSignature = new X509Certificate2Signature(myCert.SCertificate, "SHA1");
MakeSignature.SignDetached(sap, externalSignature, myCert.Chain, null, null,myCert.Tsc, 0, CryptoStandard.CMS);
st.Close();
reader.Close();
}
Figure A (original)
Figure B (after digital signature applied)
Link for Pdf files

Related

Signing an existing pdf with iText 7 is removing existing signature field rather than filling it

public void SignPdf(GenericViewModel vm)
{
bool isAppendMode = true;
string dest = #"{exportedpdf}";
string source = #"{originalpdf}";
int certificationLevel = 3;
ICipherParameters pk = _certificate.GeneratePrivateKey(vm.NDISType, 2048);
System.Security.Cryptography.X509Certificates.X509Certificate cert = new System.Security.Cryptography.X509Certificates.X509Certificate(#"{certificate}");
Org.BouncyCastle.X509.X509Certificate bcCert = new X509CertificateParser().ReadCertificate(cert.GetRawCertData());
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[1] { bcCert };
PdfReader reader = new PdfReader(source);
StampingProperties properties = new StampingProperties();
if (isAppendMode)
{
properties.UseAppendMode();
}
var outdoc = new FileStream(dest, FileMode.Create);
PdfSigner signer = new PdfSigner(reader, outdoc, properties);
var doc = signer.GetDocument();
signer.SetFieldName("Signature Field 2"); //existing signature field
signer.SetCertificationLevel(certificationLevel);
byte[] imageBytes = Convert.FromBase64String(vm.Assessor.AssessorSignature);
ImageData imageData = ImageDataFactory.Create(imageBytes);
PdfSignatureAppearance sigAppearance = signer.GetSignatureAppearance();
sigAppearance.SetSignatureGraphic(imageData);
sigAppearance.SetRenderingMode(RenderingMode.GRAPHIC);
PdfAcroForm.GetAcroForm(doc, false)
.GetField("Signature Field 2")
.SetVisibility(PdfFormField.VISIBLE);
IExternalSignature pks = new PrivateKeySignature(pk, "SHA-512");
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
outdoc.Close();
reader.Close();
}
existing pdf signature field
signed pdf
Since I am new to iText, I am looking to sign the pdf with a graphical signature appearance... I tried changing the rendering mode to the other options but nothing seemed to work, all options are not setting anything in the required signature field..

Vertical Digital Signature Appearance C# ITextSharp [duplicate]

This question already has answers here:
iTextSharp vertical SignatureAppearance
(2 answers)
Closed 3 years ago.
I have code which digitally signs pdf file which displays the signature horizontally by default, but need the signature to be place Vertical position.
I have tried rotating the rectangle to 90 or 270 but didn't worked
Working code(Print signature horizontal position)
X509Certificate2 signatureCert = new X509Certificate2(cert);
if (!cert.HasPrivateKey)
{
MessageBox.Show("Certificate does not have Private Key");
}
else
{
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
if (rsa == null)
{
if (rsa.CspKeyContainerInfo.HardwareDevice) //smartcard
{
if ((rsa.CspKeyContainerInfo.KeyContainerName == CertificateDetails.KeyContainerName) && (rsa.CspKeyContainerInfo.ProviderName == CertificateDetails.ProviderName))
{
// MessageBox.Show("Certificate Match");
}
else
{
MessageBox.Show("Incorrect Certificate Provider Details.");
}
}
}
}
X509CertificateParser cp = new X509CertificateParser();
X509Certificate[] chain = new X509Certificate[] { cp.ReadCertificate(cert.RawData) };
IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");
PdfReader pdfReader = new PdfReader(source);
PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, new
FileStream(dest, FileMode.Create, FileAccess.Write), '\0', null, true);
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
signatureAppearance.Reason = reason;
signatureAppearance.Location = location;
signatureAppearance.SetVisibleSignature(new iTextSharp.text.Rectangle(50, 250, 250, 30), 1, signatureName);
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
pdfStamper.Close();
Expecting the output to display signature in vertical position.
Thanks in advance.
The answer was given earlier.
https://stackoverflow.com/a/28042136/12237843

Itextsharp Digital sign and show info(subject and issuername) of certificate on PDF as attached image

I am working on one project using iTextSharp to digitally sign PDF file, it's workable, but need directly show the certificate's info on PDF (Please refer to attached image), how to do or set any parameter of iTextSharp?
public static X509Certificate2 cert;
//Sign with certificate selection in the windows certificate store
public static void Sign(string pdfFile, string outPdfFile){
Program.WriteLog("Signing Digital Certificate");
string IssuerName = null;
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
IssuerName = Properties.Settings.Default.IssuerName;
if (IssuerName.Length > 0)
cert = store.Certificates.Find(X509FindType.FindByIssuerName, IssuerName, false)[0];
if (cert == null)
{
//manually chose the certificate in the store
X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(store.Certificates, null, null, X509SelectionFlag.SingleSelection);
if (sel.Count > 0)
cert = sel[0];
else
{
Console.WriteLine("Certificate not found");
return;
}
}
PdfReader reader = new PdfReader(pdfFile); // source pdf file
FileStream os = new FileStream(outPdfFile, FileMode.Create); //the output pdf file
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
stamper.SetEncryption(PdfWriter.STRENGTH128BITS, "", null, PdfWriter.AllowCopy | PdfWriter.AllowPrinting);
try
{
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(cert.RawData) };
IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
//here set signatureAppearance at your will
appearance.Reason = Properties.Settings.Default.DigitalSignReason;
appearance.Location = Properties.Settings.Default.DigitalSignLocation;
appearance.Contact = Properties.Settings.Default.DigitalSignContact;
if (Properties.Settings.Default.DigitalSignAppearance == 1)
{
appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(20, 10, 170, 60), 1, "Signed");
}
appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
MakeSignature.SignDetached(appearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
//MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CADES);
}catch(Exception e){
Console.WriteLine(e.Message, 1);
File.Delete(outPdfFile);
}
finally
{
if (reader != null)
reader.Close();
if (stamper != null)
stamper.Close();
if (os != null)
os.Close();
}
}
According to your screen shot you want a special kind of signature, a certification signature. You can create such a signature by adding
appearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS;
to your code. Alternatively, to allow less changes, use CERTIFIED_FORM_FILLING or CERTIFIED_NO_CHANGES_ALLOWED.

iText C# MakeSignature.SignDetached throws NullReference exception

We are sucessfully signing PDF documents, using the C# sample C2_01_SignHelloWorld:
http://sourceforge.net/p/itextsharp/code/HEAD/tree/tutorial/signatures/chapter2/C2_01_SignHelloWorld/C2_01_SignHelloWorld.cs#l21
For a just about every PDF we sign, this works fine. However, as soon as there is one or more attachments, MakeSignature.SignDetached throws a NullReference exception.
Does someone hava an idea why this is happening?
Thanks!
Here is our code snippet:
PdfReader reader = new PdfReader(pdfFileName);
PdfSignatureAppearance signatureAppearance;
String pdfFileNameDest = pdfFileName.Substring(0, pdfFileName.LastIndexOf('.')) + "-signed" + pdfFileName.Substring(pdfFileName.LastIndexOf('.'));
FileStream fileStream = new FileStream(certFileName, FileMode.Open);
FileStream fileStreamDest = new FileStream(pdfFileNameDest, FileMode.Create);
Pkcs12Store store = new Pkcs12Store(fileStream, certPassword.ToCharArray());
String alias = "";
ICollection<X509Certificate> chain = new List<X509Certificate>();
try
{
// Search private key
foreach (string al in store.Aliases)
if (store.IsKeyEntry(al) && store.GetKey(al).Key.IsPrivate)
{
alias = al;
break;
}
AsymmetricKeyEntry pk = store.GetKey(alias);
foreach (X509CertificateEntry c in store.GetCertificateChain(alias))
chain.Add(c.Certificate);
RsaPrivateCrtKeyParameters parameters = pk.Key as RsaPrivateCrtKeyParameters;
PdfStamper stamper = PdfStamper.CreateSignature(reader, fileStreamDest, '\0');
signatureAppearance = stamper.SignatureAppearance;
signatureAppearance.Reason = "Because we need to sign it";
signatureAppearance.Contact = "We";
signatureAppearance.Location = "Server";
IExternalSignature pks = new PrivateKeySignature(parameters, DigestAlgorithms.SHA256);
MakeSignature.SignDetached(signatureAppearance, pks, chain, null, null, null, 0, CryptoStandard.CMS);
signatureAppearance.SetVisibleSignature(new iTextSharp.text.Rectangle(100, 100, 250, 150), 1, null);
stamper.Close();
}
catch (Exception ex)
{
MessageBox.Show("Exception: " + ex.ToString());
}

Sign PDF with iTextSharp 5.3.3 and USB token

I'm new to iTextSharp (and StackOverFlow). I'm trying to sign a PDF in C# using external USB token. I try using the follow code I've digged from the internet.
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
//Get Sertifiacte
X509Certificate2 certClient = null;
X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
st.Open(OpenFlags.MaxAllowed);
X509Certificate2Collection collection = X509Certificate2UI.SelectFromCollection(st.Certificates, "Please choose certificate:", "", X509SelectionFlag.SingleSelection);
if (collection.Count > 0){
certClient = collection[0];
}
st.Close();
//Get Cert Chain
IList<Org.BouncyCastle.X509.X509Certificate> chain = new List<Org.BouncyCastle.X509.X509Certificate>();
X509Chain x509chain = new X509Chain();
x509chain.Build(certClient );
foreach (X509ChainElement x509ChainElement in x509chain.ChainElements){
chain.Add(DotNetUtilities.FromX509Certificate(x509ChainElement.Certificate));
}
PdfReader reader = new PdfReader(sourceDocument);
FileStream resStream = new FileStream(resultDocument, FileMode.Create, FileAccess.ReadWrite);
PdfStamper stamper = PdfStamper.CreateSignature(reader, resStream , '\0', null, true);
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.Reason = reason;
appearance.Location = location;
appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(20, 10, 170, 60), 1, "Signed");
X509Certificate2Signature es = new X509Certificate2Signature(certClient, "SHA-1");
MakeSignature.SignDetached(appearance, es, chain, null, null, null, 0, CryptoStandard.CMS);
The problem is that I receive an exception:
System.Security.Cryptography.CryptographicException was unhandled
Message=Invalid type specified.
Source=mscorlib
StackTrace:
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.Utils._GetKeyParameter(SafeKeyHandle hKey, UInt32 paramID)
at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
at iTextSharp.text.pdf.security.X509Certificate2Signature..ctor(X509Certificate2 certificate, String hashAlgorithm)
at WindowsFormsApplication1.PDFSignerHelper.signPdfFile(String sourceDocument, String resultDocument, X509Certificate2 certClient, String reason, String location)
InnerException:
This approach works fine for us (iTextSharp 5.3.3). We use smart-card and USB-token (vendor - www.author.kiev.ua):
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(store.Certificates, null, null, X509SelectionFlag.SingleSelection);
X509Certificate2 cert = sel[0];
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] {
cp.ReadCertificate(cert.RawData)};
IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");
PdfReader pdfReader = new PdfReader(pathToBasePdf);
signedPdf = new FileStream(pathToBasePdf, FileMode.Create);
pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
signatureAppearance.SignatureGraphic = Image.GetInstance(pathToSignatureImage);
signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 250, 150), pdfReader.NumberOfPages, "Signature");
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
I have made a c# project that can sign a PDF from the windows store, SmartCard or a Pfx/P12 file
Maybe it can be useful for you
using System;
using System.Windows.Forms;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
namespace SignPdf
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private SecureString GetSecurePin(string PinCode)
{
SecureString pwd = new SecureString();
foreach (var c in PinCode.ToCharArray()) pwd.AppendChar(c);
return pwd;
}
private void button1_Click(object sender, EventArgs e)
{
//Sign from SmartCard
//note : ProviderName and KeyContainerName can be found with the dos command : CertUtil -ScInfo
string ProviderName = textBox2.Text;
string KeyContainerName = textBox3.Text;
string PinCode = textBox4.Text;
if (PinCode != "")
{
//if pin code is set then no windows form will popup to ask it
SecureString pwd = GetSecurePin(PinCode);
CspParameters csp = new CspParameters(1,
ProviderName,
KeyContainerName,
new System.Security.AccessControl.CryptoKeySecurity(),
pwd);
try
{
RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp);
// the pin code will be cached for next access to the smart card
}
catch (Exception ex)
{
MessageBox.Show("Crypto error: " + ex.Message);
return;
}
}
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = null;
if ((ProviderName == "") || (KeyContainerName == ""))
{
MessageBox.Show("You must set Provider Name and Key Container Name");
return;
}
foreach (X509Certificate2 cert2 in store.Certificates)
{
if (cert2.HasPrivateKey)
{
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert2.PrivateKey;
if (rsa == null) continue; // not smart card cert again
if (rsa.CspKeyContainerInfo.HardwareDevice) // sure - smartcard
{
if ((rsa.CspKeyContainerInfo.KeyContainerName == KeyContainerName) && (rsa.CspKeyContainerInfo.ProviderName == ProviderName))
{
//we find it
cert = cert2;
break;
}
}
}
}
if (cert == null)
{
MessageBox.Show("Certificate not found");
return;
}
SignWithThisCert(cert);
}
private void button2_Click(object sender, EventArgs e)
{
//Sign with certificate selection in the windows certificate store
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = null;
//manually chose the certificate in the store
X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(store.Certificates, null, null, X509SelectionFlag.SingleSelection);
if (sel.Count > 0)
cert = sel[0];
else
{
MessageBox.Show("Certificate not found");
return;
}
SignWithThisCert(cert);
}
private void button3_Click(object sender, EventArgs e)
{
//Sign from certificate in a pfx or a p12 file
string PfxFileName = textBox5.Text;
string PfxPassword = textBox6.Text;
X509Certificate2 cert = new X509Certificate2(PfxFileName, PfxPassword);
SignWithThisCert(cert);
}
private void SignWithThisCert(X509Certificate2 cert)
{
string SourcePdfFileName = textBox1.Text;
string DestPdfFileName = textBox1.Text + "-Signed.pdf";
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(cert.RawData) };
IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");
PdfReader pdfReader = new PdfReader(SourcePdfFileName);
FileStream signedPdf = new FileStream(DestPdfFileName, FileMode.Create); //the output pdf file
PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
//here set signatureAppearance at your will
signatureAppearance.Reason = "Because I can";
signatureAppearance.Location = "My location";
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
//MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CADES);
MessageBox.Show("Done");
}
}
}
The same code as above but uses a certificate file instead of store to sign a PDF document on the last page.
X509Certificate2 cert = new X509Certificate2("C:\\mycert.p12");
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] {
cp.ReadCertificate(cert.RawData)};
IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-1");
PdfReader pdfReader = new PdfReader("C:\\multi-page-pdf.pdf");
var signedPdf = new FileStream("C:\\multi-page-pdf-signed.pdf", FileMode.Create);
var pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
signatureAppearance.SignatureGraphic = Image.GetInstance("C:\\logo.png");
signatureAppearance.Reason = "Because I can";
signatureAppearance.Location = "My location";
signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 250, 150), pdfReader.NumberOfPages, "Signature");
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
Copy, paste, import needed libraries and go work on something else.

Categories

Resources