Mentre .NET supporta pienamente classi per le specifiche XML in fatto di firme, per la Codifica non esiste nessuna classe specifica.. nemmeno una.

Attenzione, questo non significa che operazioni di codifica risultino impossibili.. anzi. Ricordiamoci delle classi di Cryptography viste nei precedenti post.

Continuando a prendere come esempio il file xml (Sec22 e Sec23) andiamo a vedere come possiamo trattare questo nodo al fine di codificarlo. Dando per scontato la totale assenza di una chiave, la prima cosa che dobbiamo fare è quella di andarla a creare. Per fare questo avremmo bisogno di creare una chiave simmetrica, codificarla e rendere il risultato codificato in Base64. Via al codice.

 Rijndael rKey = new RijndaelManaged();
 RSACryptoServiceProvider rsa = 
new RSACryptoServiceProvider();
 MemoryStream encryptedData = 
new MemoryStream();
 
 
int start = 0;
 
do
 
{
    
byte[] keyMaterial = new byte[16];
    Array.Copy(rKey.Key, start, keyMaterial, 0, 16);
10     
byte[] encryptedSessionKey = rsa.Encrypt(keyMaterial, false);
11     encryptedData.Write(encryptedSessionKey, 0,
12        (
int)encryptedSessionKey.Length);
13     start += 16;
14  } 
while(start < rKey.Key.Length);
15  encryptedData.Position = 0;
16  String rToBase64 = Convert.ToBase64String(encryptedData.GetBuffer(),
17     0, (
int)encryptedData.Length);

Una volta che abbiamo la chiave di sessione criptata, la creazione del giusto XmlElement inizia ad essere la parte a cui dobbiamo prestare maggiore attenzione. Ricordiamoci che dobbiamo generare il giusto Element al momento giusto.. in questo modo potremmo creare gli elementi di codifica appropriati. Vediamolo meglio.

 XmlDocument keyExchDoc = new XmlDocument();
 XmlElement encryptedKey = keyExchDoc.CreateElement("EncryptedKey");
 keyExchDoc.AppendChild(encryptedKey);
 XmlAttribute carriedKeyName = keyExchDoc.CreateAttribute("CarriedKeyName");
 carriedKeyName.Value = "Ale's Session Key";
 encryptedKey.Attributes.Append(carriedKeyName);
 
 XmlElement encryptionMethod = keyExchDoc.CreateElement("EncryptionMethod");
 encryptedKey.AppendChild(encryptionMethod);
10  XmlAttribute encryptionAlgorithm = keyExchDoc.CreateAttribute("Algorithm");
11  encryptionAlgorithm.Value = "http://www.w3.org/2001/04/xmlenc#rsa-1_5";
12  encryptionMethod.Attributes.Append(encryptionAlgorithm);
13  
14  XmlElement keyInfo = keyExchDoc.CreateElement("ds", "KeyInfo",
15     "http://www.w3.org/2000/09/xmldsig#");
16  encryptedKey.AppendChild(keyInfo);
17  
18  XmlElement keyName = keyExchDoc.CreateElement("ds", "KeyName", 
null);
19  keyName.InnerText = "Ale's Private Key";
20  keyInfo.AppendChild(keyName);
21  
22  XmlElement cipherData = keyExchDoc.CreateElement("CipherData");
23  encryptedKey.AppendChild(cipherData);
24  
25  XmlElement cipherValue = keyExchDoc.CreateElement("CipherValue");
26  cipherValue.InnerText = rToBase64;
27  cipherData.AppendChild(cipherValue);
28  

A questo punto, chiamare OuterXml sul campo keyExchDoc produce come output il seguente documento.

<EncryptedKey CarriedKeyName="Ale's Session Key">
   <EncryptionMethod 
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
   <ds:KeyInfo 
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <KeyName>
Ale's Private Key</KeyName>
   <
/ds:KeyInfo>
   <CipherData>
      <CipherValue>
CQu3/R138mrMDuLuY74C1....</CipherValue>
   <
/CipherData>
<
/EncryptedKey>

Mettiamo il caso che Alessio abbia bisogno di decodificare il tutto con la sua chiave privata di nome "Ale's Private Key". Bene, ora immaginiamo che Alessio ha ricevuto questo documento ed ha correttamente trasformato e decodificato il il testo contenuto dei CipherValue . A questo punto, è possibile, inviare l'ordine di Alessio con l'elemento Pagamento correttamente codificato utilizzando questo codice.

String appPath = Application.StartupPath;
XmlDocument paymentDoc = 
new XmlDocument();
paymentDoc.Load(appPath + @"\Ordine.XML");
XmlElement paymentElem =
   (XmlElement)paymentDoc.SelectSingleNode("Ordine/Pagamento");

byte[] paymentXmlInfo = Encoding.Unicode.GetBytes(paymentElem.OuterXml);
MemoryStream ms = 
new MemoryStream();
CryptoStream csBase64 = 
new CryptoStream(ms,
   
new ToBase64Transform(),
   CryptoStreamMode.Write);
CryptoStream csRijndael = 
new CryptoStream(csBase64,
   rKey.CreateEncryptor(),
   CryptoStreamMode.Write);
csRijndael.Write(paymentXmlInfo, 0,
   (
int)paymentXmlInfo.Length);
csRijndael.FlushFinalBlock();
String base64enc = Encoding.ASCII.GetString(ms.GetBuffer(),
   0, (
int)ms.Length);

A questo punto, abbiamo le informazioni di pagamento codificare. Abbiamo ora bisogno di creare l'elemento EncryptedData e aggiungere l'informazione sulla chiave insieme al risultato del nostro lavoro.

XmlElement encryptedData = paymentDoc.CreateElement("EncryptedData");
XmlAttribute encryptedType = paymentDoc.CreateAttribute("Type");
encryptedType.Value = "http://www.w3.org/2001/04/xmlenc#Element";
encryptedData.Attributes.Append(encryptedType);

XmlElement keyInfo = paymentDoc.CreateElement("ds", "KeyInfo",
   "http://www.w3.org/2000/09/xmldsig#");
encryptedData.AppendChild(keyInfo);

XmlElement keyName = paymentDoc.CreateElement("ds", "KeyName", 
null);
keyName.InnerText = "Ale's Session Key";
keyInfo.AppendChild(keyName);

XmlElement cipherData = paymentDoc.CreateElement("CipherData");
encryptedData.AppendChild(cipherData);

XmlElement cipherValue = paymentDoc.CreateElement("CipherValue");
cipherValue.InnerText = base64enc; cipherData.AppendChild(cipherValue);

XmlElement orderElem =
   (XmlElement)paymentDoc.SelectSingleNode("Ordine");

orderElem.ReplaceChild(encryptedData, paymentElem);

Adesso non resta che sovrascrivere il valore di Pagamento del file originale con quello risultate dalle nostre operazioni di codifica. Questo ci porta ad avere come risultato il seguente documento XML.

<Ordine>
   <Items>
      <Item 
ID="123456789">
         <Description>
Il mio ordine</Description>
         <Price>
0.99</Price>
      <
/Item>
   <
/Items>
   <EncryptedData 
Type="http://www.w3.org/2001/04/xmlenc#Element">
      <ds:KeyInfo 
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
         <KeyName>
Ale's Session Key</KeyName>
      <
/ds:KeyInfo>
      <CipherData>
         <CipherValue>
lupcw1DYZ9k0Tr1rX2TN...</CipherValue>
      <
/CipherData>
   <
/EncryptedData>
<
/Ordine>

Fatto