XML è un linguaggio molto comodo che si sta diffondendo sempre di più per contenere e rappresentare dati, dato che i documenti di questo tipo possono contenere anche informazioni che devono mantenere una integrità ed avere la possibilità di rilevare il cambiamento anche di un solo carattere.
Il W3C ha creato perciò uno standard volto a firmare documenti XML che prende il nome di XML Digital Segnature (XMLDSIG).
Una firma digitale consiste nel calcolare un digest, il risultato di un'operazione matematica della quale è impossibile fare l'operazione inversa, su un documento, criptarlo mediante un algoritmo con chiave asimmetrica (chiave private per criptare) e unire il documento XML con la rappresentazione della firma.
In questo modo chi vuole validare la firma andrà a calcolare a sua volta il digest del documento XML originale presunto e lo confronterà con il digest decriptato con la chiave pubblica. Se combaciano il documento è integro.
Il .NET Framework dispone di un insieme di classi per supportare XMLDSIG che sono contenute nel namespace System.Security.Cryptography.Xml (in unione con System.Security.Cryptography per la crittografia) dell'assembly System.Security.
Lo script proposto preleva un file XML tramite upload e restituisce il documento firmato:
// Carico il documento XML XmlDocument doc = new XmlDocument(); doc.Load(xmlFile.PostedFile.InputStream); // Elimino il nodo di dichiarazione xml (<?xml.. foreach (XmlNode n in doc.ChildNodes) if (n.NodeType == XmlNodeType.XmlDeclaration) doc.RemoveChild(n); // Creo l'oggetto per firmare SignedXml xs = new SignedXml(); // Creo un object con la lista degli XmlNode da firmare // in questo caso il DocumentElement DataObject data = new DataObject(); data.Data = doc.ChildNodes; data.Id = "MyDocId"; // Lo aggiungo alla lista di oggetti da firmare xs.AddObject(data); // Indico che gli algoritmi RSA devono memorizzare // le chiavi sulla macchina RSACryptoServiceProvider.UseMachineKeyStore = true; // Creo un algoritmo RSA per criptare il digest RSA key = new RSACryptoServiceProvider(); // Indico di usare questo algoritmo xs.SigningKey = key; // Creo una KeyInfo sulla base dell'algoritmo // per infomare il tipo di criptazione utilizzata // e mostrare la chiave pubblica KeyInfo ki = new KeyInfo(); RSAKeyValue rsa = new RSAKeyValue(key); ki.AddClause(rsa); xs.KeyInfo = ki; // Aggiungo la reference al mio oggetto // con lo stesso Uri dell'Id Reference r = new Reference(); r.Uri = "#MyDocId"; xs.AddReference(r); // Calcolo la firma xs.ComputeSignature(); // Mando in output l'xml risultante Response.Clear(); Response.ContentType = "text/xml"; Response.Write(xs.GetXml().OuterXml); Response.End();
Il codice è ben commentato. Nell'esempio viene usato l'algoritmo RSA e le chiavi sono depositate nella macchina. Il risultato è una root Signature contenente le informazioni sul digest e la chiave pubblica per effettuare la decryption.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
I più letti di oggi
- Creare un adorner personalizzato per le trading cards di PivotViewer in Silverlight 5.0
- Copiare uno Stream con il .NET Framework 4.0
- Supporto alla validazione client-side in una data annotation su ASP.NET MVC 3
- Disabilitare automaticamente un workflow di GitHub (parte 2)
- Dependency injection con Minimal API di ASP.NET Core
- Migliorare l'organizzazione delle risorse con Azure Policy
- Sfruttare una CDN con i bundle di ASP.NET
- Creare applicazioni in real-time con ASP.NET SignalR
- Memorizzare posizione e dimensioni della finestra di una applicazione OOB Silverlight 4.0
- Web Camp - HTML5 per il web di oggi