A feladatban a mellékelt PersonalInfo.xml állományt fogjuk egy aláírással hitelesíteni. A Form 4 gombja segítségével négy művelet végezhető el egymás után, most ezeket ismertetjük.
Az üzleti alkalmazások esetén alkalmazott megoldást modellezzük, ahol a szakemberek a nyilvános kulcsú titkosítást és a digitális aláírást alkalmazhatják. A nyilvános kulcsú titkosítás esetén az egész információ titkosításra kerül a nyilvános kulccsal, majd a visszafejtés történik meg a privát kulcs segítségével.
A digitális aláírás esetén csak az „üzenetkivonat” (message digest) titkosítása valósul meg a privát kulcs segítségével, majd a kivonat értékét visszafejtik a nyilvános kulccsal. Ezt követően újrakalkulálódik az üzenetkivonat, ellenőrizendő az üzenet hitelessége.
A feladatban az utóbbit fogjuk alkalmazni, a digitális aláírás algoritmusát (DSA) felhasználva, melyet a .NET DSA nevű osztálya segítségével érhetünk el. A modell érdekében egy képzeletbeli vevőinformációs dokumentumot reprezentál a PersonalInfo.xml állomány, mely vásárlás, vagy egyéb tranzakciós művelet során mozog a hálózatban. Az információ aláírása lehetővé teszi, hogy a befogadó ellenőrizze, valóban az információ tulajdonosa küldte az adathalmazt.
Ahogy a végeredményben is látható lesz nem egészen titkosításról van itt szó, hanem egy kiegészítő – mindkét fél, de csak a jogosult felek által értelmezhető – adathalmaz beleszövéséről az üzenetbe.
Kulcsgenerálás
Ebben a műveletben elkészítünk egy XML állományt (DSAKeyPair.xml), mely tartalmazza a nyilvános és a privát kulcsot is. Ehhez szükség van egy DSA objektumra.
DSA key = DSA.Create();
string keyXML = key.ToXmlString(true);
XmlDocument doc = new XmlDocument();
doc.LoadXml(keyXML);
doc.Save("DSAKeyPair.xml");
A második műveletben egy olyan XML-t készítünk (DSAPublicKey.xml), mely csak a nyilvános kulcsot tartalmazza.
keyXML = key.ToXmlString(false);
doc = new XmlDocument();
doc.LoadXml(keyXML);
doc.Save("DSAPublicKey.xml");
XML aláírása
Elkészítettünk egy Signing nevű osztályt, melynek statikus Sign metódusában írjuk alá az információs XML-t. Először betöltjük egy string-be a mindkét kulcsot tartalmazó állományt.
XmlDocument keypairDoc = new XmlDocument();
keypairDoc.Load("DSAKeyPair.xml");
string keyXML = keypairDoc.InnerXml;
A SignedXml osztály kulcsfontosságú az aláírásban. Az osztály fogja generálni az aláírást a digitális aláírási algoritmus felhasználásával. Ehhez megkapja a generált kulcsot.
SignedXml signedxml = new SignedXml();
DSA key = DSA.Create();
key.FromXmlString(keyXML);
signedxml.SigningKey = key;
Betöltjük az információs XML-t.
XmlDocument doc = new XmlDocument();
doc.Load("PersonalInfo.xml");
Egy DataObject objektum fogja hordozni az aláírandó dokumentumot, ezt átadjuk az osztálynak.
DataObject dObject = new DataObject();
dObject.Data = doc.ChildNodes;
dObject.Id = "PersonalInfo";
signedxml.AddObject(dObject);
Ezt követően kap az osztály még egy referenciát a DataObject objektumra.
Reference reference = new Reference();
reference.Uri = "#PersonalInfo";
signedxml.AddReference(reference);
Majd a kapott információk alapján a ComputeSignature metódus segítségével elkészíti az aláírást és az információt is tartalmazó adathalmazt.
signedxml.ComputeSignature();
Az adathalmazt visszaadja a metódus, melyet felhasználunk az ellenőrzéshez.
XmlElement xmlSignature = signedxml.GetXml();
string signeddata = xmlSignature.OuterXml;
return signeddata;
Ellenőrzés
A CheckSign metódussal ellenőrizzük, hogy az XML tartalmazza-e az aláírást. A műveletben az információt visszafejtjük a nyilvános kulccsal, majd összehasonlításra kerülnek az üzenettartalmak. Ehhez betöltjük a nyilvános kulcsot tartalmazó állományt.
XmlDocument keypairdoc = new XmlDocument();
keypairdoc.Load("DSAPublicKey.xml");
string keypair = keypairdoc.InnerXml;
A kulcsot átadjuk az aláírást tartalmazó osztálynak.
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new DSAKeyValue(key));
signedxml.KeyInfo = keyInfo;
Betöltjük az adathalmazt, mely tartalmaz aláírást.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(signeddata);
Majd megkeressük az első <signature> tagot.
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
signedxml.LoadXml((XmlElement)nodeList[0]);
A SignedXml osztály CheckSignature metódusa ellenőrzi a helyességet.
signedxml.CheckSignature()
...
Az aláírt információs állományt kimenthetjük egy SignedPersonalInfo.xml állományba az „Aláírt XML mentése” feliratú gombbal. Az aláírás ellenőrzése után a Form ListBox kontroljában ellenőrizhetjük, hogy az aláírás helyes-e. A művelet természetesen a fogadó állomáson történhet meg, a nyilvános kulcs ugyanis ott is megtalálható éles helyzetben.