Cześć,
piszę sobie program, który ma m.im. zapisywać dane do pliku XML i chciałbym zaszyfrować niektóre klucze w tym pliku. W tym celu użyłem klasy w System.Security.Cryptography.Xml, a konkretnie przykładu z tej strony:
https://msdn.microsoft.com/pl-pl/library/ms229746(v=vs.110).aspx
Zmodyfikowałem funkcję Encrypt, tak by jako drugi argument przyjmowała zamiast nazwy klucza gotowy XmlElement:
public void Encrypt(XmlDocument Doc, XmlElement ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName)
{
// Check the arguments.
if (Doc == null)
throw new ArgumentNullException("Doc");
if (ElementToEncrypt == null)
throw new ArgumentNullException("ElementToEncrypt");
if (EncryptionElementID == null)
throw new ArgumentNullException("EncryptionElementID");
if (Alg == null)
throw new ArgumentNullException("Alg");
if (KeyName == null)
throw new ArgumentNullException("KeyName");
////////////////////////////////////////////////
// Find the specified element in the XmlDocument
// object and create a new XmlElemnt object.
////////////////////////////////////////////////
// XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
XmlElement elementToEncrypt = ElementToEncrypt;
// Throw an XmlException if the element was not found.
if (elementToEncrypt == null)
{
throw new XmlException("The specified element was not found");
}
RijndaelManaged sessionKey = null;
// MessageBox.Show(Doc.GetElementsByTagName(ElementToEncrypt).Count.ToString());
try
{
//////////////////////////////////////////////////
// Create a new instance of the EncryptedXml class
// and use it to encrypt the XmlElement with the
// a new random symmetric key.
//////////////////////////////////////////////////
// Create a 256 bit Rijndael key.
sessionKey = new RijndaelManaged();
sessionKey.KeySize = 256;
EncryptedXml eXml = new EncryptedXml();
byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
////////////////////////////////////////////////
// Construct an EncryptedData object and populate
// it with the desired encryption information.
////////////////////////////////////////////////
EncryptedData edElement = new EncryptedData();
edElement.Type = EncryptedXml.XmlEncElementUrl;
edElement.Id = EncryptionElementID;
// Create an EncryptionMethod element so that the
// receiver knows which algorithm to use for decryption.
edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
// Encrypt the session key and add it to an EncryptedKey element.
EncryptedKey ek = new EncryptedKey();
byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false);
ek.CipherData = new CipherData(encryptedKey);
ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
// Create a new DataReference element
// for the KeyInfo element. This optional
// element specifies which EncryptedData
// uses this key. An XML document can have
// multiple EncryptedData elements that use
// different keys.
DataReference dRef = new DataReference();
// Specify the EncryptedData URI.
dRef.Uri = "#" + EncryptionElementID;
// Add the DataReference to the EncryptedKey.
ek.AddReference(dRef);
// Add the encrypted key to the
// EncryptedData object.
edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
// Set the KeyInfo element to specify the
// name of the RSA key.
// Create a new KeyInfoName element.
KeyInfoName kin = new KeyInfoName();
// Specify a name for the key.
kin.Value = KeyName;
// Add the KeyInfoName element to the
// EncryptedKey object.
ek.KeyInfo.AddClause(kin);
// Add the encrypted element data to the
// EncryptedData object.
edElement.CipherData.CipherValue = encryptedElement;
////////////////////////////////////////////////////
// Replace the element from the original XmlDocument
// object with the EncryptedData element.
////////////////////////////////////////////////////
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
}
catch (Exception e)
{
// re-throw the exception.
throw e;
}
finally
{
if (sessionKey != null)
{
sessionKey.Clear();
}
}
}
i dalej mam pętlę foreach
XmlNodeList pass = XmlDoc.GetElementsByTagName("pass");
foreach (XmlNode node in pass)
{
XmlElement elementToEncrypt = node as XmlElement;
try
{
// XmlElement pass = XmlDoc.GetElementsByTagName("pas")[listBox1.SelectedIndex] as XmlElement;
Encrypt(XmlDoc, elementToEncrypt, "EncryptedElement2", rsaKey, "rsaKey");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
// Clear the RSA key.
rsaKey.Clear();
}
}
XmlDoc.Save("hosts.xml");
po uruchomieniu kody pojawia się błąd: "Lista elementów zmieniła się. Nie można kontynuować operacji wyliczenia." Próbowałem to zrobić na pętli for i while, ale zawsze szyfruje się tylko pierwszy, albo ostatni klucz w pliku XML