.Net Firma digitale per file pdf con VB.Net e C#

Articolo che fornisce indicazioni sulla possibilità di firmare digitalmente i documenti tramite un certificato.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

In questo articolo verrà affrontato un tema di grande attualità e spesso non facile per la complessità che  trova difficoltà tra i programmatori, la firma digitale.
Vedremo, come aggiungere in un progetto di tipo “Windows Application” la possibilità di firmare i documenti in formato “Pdf” tramite un certificato presente sul nostro computer.
Con la firma digitale, si autentica un documento in maniera legale, premettendo in questo modo di avere valenza legale nei confronti di terzi.
Per la firma dei file in formato “Pdf” utilizzeremo la libreria “iTextSharp” che si presta bene per questo tipo di attività.
Dopo aver selezionato un certificato dal nostro computer, questo verrà utilizzato per firmare il documento, il tutto come si vede in figura 1.

Figura 1 - La firma del documento


Oltre alla firma, sarà possibile aggiungere anche il dettaglio della firma, con alcune informazioni utili.

Creazione del progetto

Prima di creare un progetto, dobbiamo creare (anche con Microsoft Word) un file pdf, con il quale effettuare la prova e quindi la firma, dopo averlo creato passiamo al ambiente di sviluppo Visual Studio.
Si crea un nuovo progetto di tipo “Windows Application” con il linguaggio di proprio interesse, una volta creato il progetto dobbiamo aggiungere il riferimento alla libreria “iTextSharp”.
Dobbiamo aprire la finestra Nuget, e cercare il componente. Da esplora soluzione, facciamo click con il tasto destro, e dal menu di scelta rapida selezioniamo la voce “Gestione pacchetti Nuget” , nella finestra che viene aperta, in alto a destra scrivere “iTextSharp” , e selezionare il componente con tale nome, il tutto come mostrato in figura 2.

Figura 2 – L’aggiunta del componente

A questo punto facciamo click sulla voce “Installa” in modo che verrà aggiunto al progetto, naturalmente dobbiamo accettare i termini di licenza.

Stesura del codice


Dopo aver aggiunto il componente, non ci resta che aggiungere i riferimenti a tale libreria, in particolare lo spazio dei nomi.
In alto sopra ad ogni dichiarazione scriviamo lo spazio dei nomi, qui di seguito si riporta l’esempio per entrambi i linguaggi.

VB.Net
Imports System.Security.Cryptography.X509Certificates
Imports iTextSharp.text.pdf
Imports iTextSharp.text.pdf.security
C#
using System.Security.Cryptography.X509Certificates;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;

Ora dobbiamo scrivere una funzione, che ci visualizza all’utente certificati presenti sul nostro pc da selezionare per apportare la firma. Da ricordare che in VB.Net, dobbiamo aggiungere il riferimento a “System.Security” dalla finestra di “esplora soluzioni", per gestire la classe statica “X509Certificate2UI”.

La funzione, seleziona i certificati e visualizza a Video il certificato.
Qui di seguito si riporta il frammento di codice delle suddette operazioni

VB.Net 
Public Function SelezionaCertificatoDaPc() As X509Certificate2
Try
Dim certificatoSelezionato As X509Certificate2 = Nothing
Dim x509Store As X509Store = New X509Store(StoreName.My, StoreLocation.CurrentUser)
x509Store.Open(OpenFlags.[ReadOnly])
Dim elencoCertificati As X509Certificate2Collection = x509Store.Certificates
Dim certificatiTrovati As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(elencoCertificati, "Elenco certificati", "Seleziona certificato", X509SelectionFlag.SingleSelection)
If certificatiTrovati.Count > 0 Then
Dim certEnum As X509Certificate2Enumerator = certificatiTrovati.GetEnumerator()
certEnum.MoveNext()
certificatoSelezionato = certEnum.Current
End If
x509Store.Close()
Return certificatoSelezionato
Catch ex As Exception
Throw
End Try
End Function
C#
public X509Certificate2 SelezionaCertificatoDaPc()
{
try
{
X509Certificate2 certificatoSelezionato = null;
X509Store x509Store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
x509Store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection elencoCertificati = x509Store.Certificates;
X509Certificate2Collection certificatiTrovati = X509Certificate2UI.SelectFromCollection(elencoCertificati, "Elenco certificati", "Seleziona certificato", X509SelectionFlag.SingleSelection);
if (certificatiTrovati.Count > 0)
{
X509Certificate2Enumerator certEnum = certificatiTrovati.GetEnumerator();
certEnum.MoveNext();
certificatoSelezionato = certEnum.Current;
}
x509Store.Close();
return certificatoSelezionato;
}
catch (Exception ex)
{
throw;
}

Torniamo in visualizzazione grafica della nostra form e facciamo doppio click sul pulsante, il quale avrà il compito di firmare il documento.
In visualizzazione codice per l’evento click, utilizzeremo le classi presenti nel componente ITextSharp, il quale oltre a leggere il file pdf, verrà inserito il certificato ed un dettaglio.
Dobbiamo indicare anche un percorso e nome file di destinazione, con il quale verrà creato un nuovo file pdf, con l’aggiunta della firma.
Il metodo “SignDetached” della classe “MakeSignature” applicherà la firma.
Qui di seguito le suddetti operazioni per i linguaggi di programmazione Visual Basic Net e C#.

VB.Net
Private Sub BtnFirma_Click(sender As Object, e As EventArgs) Handles BtnFirma.Click
Try
Dim cert As X509Certificate2 = SelezionaCertificatoDaPc()
Dim cp As Org.BouncyCastle.X509.X509CertificateParser = New Org.BouncyCastle.X509.X509CertificateParser()
Dim chain As Org.BouncyCastle.X509.X509Certificate() = New Org.BouncyCastle.X509.X509Certificate() {cp.ReadCertificate(cert.RawData)}
Dim externalSignature As IExternalSignature = New X509Certificate2Signature(cert, "SHA-1")
Dim pdfReader As PdfReader = New PdfReader("D:\FilePdf.pdf")
Dim signedPdf As FileStream = New FileStream("D:\testFilePDF_firmato.pdf", FileMode.Create)
Dim pdfStamper As PdfStamper = pdfStamper.CreateSignature(pdfReader, signedPdf, vbNullChar)
Dim signatureAppearance As PdfSignatureAppearance = pdfStamper.SignatureAppearance
signatureAppearance.Reason = "Esempio Firma"
signatureAppearance.Location = "Iprogrammatori"
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, Nothing, Nothing, Nothing, 0, CryptoStandard.CMS)
System.Diagnostics.Process.Start("D:\testFilePDF_firmato.pdf")
Catch ex As Exception
MessageBox.Show("Errore: " & ex.Message)
End Try
End Sub
C#
private void BtnFirma_Click(object sender, EventArgs e)
{
try
{
X509Certificate2 cert = SelezionaCertificatoDaPc();
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("D:\\FilePdf.pdf");
FileStream signedPdf = new FileStream("D:\\testFilePDF_firmato.pdf", FileMode.Create);
PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
signatureAppearance.Reason = "Esempio Firma";
signatureAppearance.Location = "Iprogrammatori";
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
System.Diagnostics.Process.Start("D:\\testFilePDF_firmato.pdf");
}
catch (Exception ex)
{
MessageBox.Show("Errore: " + ex.Message);
}
}

Conclusioni

L’articolo ha fornito al lettore la possibilità di avvicinarsi al mondo della crittografia con particolare attenzione alla firma digitale, un ambito molto utilizzato e che in questi ultimi anni ha trovato sempre più considerazione.
La firma digitale, oggi sempre più importante, permette di attribuire ai propri documenti un valore legale, soprattutto per la stipula dei contratti.
L’utilizzo della libreria gratuita ITextSharp fornisce allo sviluppatore interessanti funzionalità, da facilitare l’uso in tale ambito.