如何加密/解密XML文件? [英] How to encrypt/decrypt an XML file?

查看:150
本文介绍了如何加密/解密XML文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试加密/解密一个XML文件。我发现这个加密样本,但我不知道如何解密?任何想法?谢谢!

  //加载此XML文件
System.Xml.XmlDocument myDoc = new System.Xml.XmlDocument( );
myDoc.Load(@c:\persons.xml);
//获取要加密的指定元素
System.Xml.XmlElement element = myDoc.GetElementsByTagName(Persons)[0] as System.Xml.XmlElement;

//创建一个新的TripleDES键。
System.Security.Cryptography.TripleDESCryptoServiceProvider tDESkey = new System.Security.Cryptography.TripleDESCryptoServiceProvider();

//使用密钥形成加密的XML
System.Security.Cryptography.Xml.EncryptedXml encr = new System.Security.Cryptography.Xml.EncryptedXml();
encr.AddKeyNameMapping(Deskey,tDESkey);

//加密元素数据
System.Security.Cryptography.Xml.EncryptedData ed = encr.Encrypt(element,Deskey);

//用加密数据替换现有数据
System.Security.Cryptography.Xml.EncryptedXml.ReplaceElement(element,ed,false);

//使用加密数据保存xml文件
myDoc.Save(@c:\encryptedpersons.xml);

但我不知道我会如何解密?有任何想法吗?谢谢!

解决方案

这样的一个例子:

 code> public static class Encryption 
{
private const string InitVector =T = A4rAzu94ez-dra;
private const int KeySize = 256;
private const int PasswordIterations = 1000; // 2;
private const string SaltValue =d =?ustAF = UstenAr3B @ pRu8 = ner5sW& h59_Xe9P2za-eFr2fa& ePHE @ ras!a + uc @;

public static string Decrypt(string encryptedText,string passPhrase)
{
byte [] encryptedTextBytes = Convert.FromBase64String(encryptedText);
byte [] initVectorBytes = Encoding.UTF8.GetBytes(InitVector);
byte [] passwordBytes = Encoding.UTF8.GetBytes(passPhrase);
string plainText;
byte [] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue);

Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passwordBytes,saltValueBytes,PasswordIterations);
byte [] keyBytes = password.GetBytes(KeySize / 8);

RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC};

尝试
{
使用(ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(keyBytes,initVectorBytes))
{
using(MemoryStream memoryStream = new MemoryStream(encryptedTextBytes )
{
using(CryptoStream cryptoStream = new CryptoStream(memoryStream,decryptor,CryptoStreamMode.Read))
{
// TODO:需要研究一下这个。假设加密的文本比普通的更长,但是可能有一个更好的方法
byte [] plainTextBytes = new byte [encryptedTextBytes.Length];

int decryptptedByteCount = cryptoStream.Read(plainTextBytes,0,plainTextBytes.Length);
plainText = Encoding.UTF8.GetString(plainTextBytes,0,decryptptedByteCount);
}
}
}
}
catch(CryptographicException)
{
plainText = string.Empty; //假设错误是由无效密码造成的
}

return plainText;
}

public static string Encrypt(string plainText,string passPhrase)
{
string encryptedText;
byte [] initVectorBytes = Encoding.UTF8.GetBytes(InitVector);
byte [] passwordBytes = Encoding.UTF8.GetBytes(passPhrase);
byte [] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
byte [] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue);

Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passwordBytes,saltValueBytes,PasswordIterations);
byte [] keyBytes = password.GetBytes(KeySize / 8);

RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC};

使用(ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(keyBytes,initVectorBytes))
{
使用(MemoryStream memoryStream = new MemoryStream())
{
使用(CryptoStream cryptoStream = new CryptoStream(memoryStream,encryptor,CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes,0,plainTextBytes.Length);
cryptoStream.FlushFinalBlock();

byte [] cipherTextBytes = memoryStream.ToArray();
encryptedText = Convert.ToBase64String(cipherTextBytes);
}
}
}

return encryptedText;
}
}

编辑: p>

Sani Huttunen指出,如果您使用相同的密码加密多个数据,我上面的静态实现会出现严重的性能问题。您可以在这里阅读更多信息: http:// jmpstart。 wordpress.com/2009/09/29/proper-use-of-rfc2898derivebytes/



编辑:非静态如果您需要使用相同的密码(〜32ms original〜1ms new)执行多次加密/解密,则执行效率要高得多。

  public class SimpleEncryption 
{
#region构造函数
public SimpleEncryption(string password)
{
byte [] passwordBytes = Encoding.UTF8.GetBytes(password);
byte [] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue);

_DeriveBytes = new Rfc2898DeriveBytes(passwordBytes,saltValueBytes,PasswordIterations);
_InitVectorBytes = Encoding.UTF8.GetBytes(InitVector);
_KeyBytes = _DeriveBytes.GetBytes(32);
}
#endregion

#region私人字段
private readonly Rfc2898DeriveBytes _DeriveBytes;
private readonly byte [] _InitVectorBytes;
private readonly byte [] _KeyBytes;
#endregion

private const string InitVector =T = A4rAzu94ez-dra;
private const int PasswordIterations = 1000; // 2;
private const string SaltValue =d =?ustAF = UstenAr3B @ pRu8 = ner5sW& h59_Xe9P2za-eFr2fa& ePHE @ ras!a + uc @;

public string Decrypt(string encryptedText)
{
byte [] encryptedTextBytes = Convert.FromBase64String(encryptedText);
string plainText;

RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC};

尝试
{
使用(ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(_KeyBytes,_InitVectorBytes))
{
using(MemoryStream memoryStream = new MemoryStream(encryptedTextBytes )
{
using(CryptoStream cryptoStream = new CryptoStream(memoryStream,decryptor,CryptoStreamMode.Read))
{
// TODO:需要研究一下这个。假设加密的文本比普通的更长,但是可能有一个更好的方法
byte [] plainTextBytes = new byte [encryptedTextBytes.Length];

int decryptptedByteCount = cryptoStream.Read(plainTextBytes,0,plainTextBytes.Length);
plainText = Encoding.UTF8.GetString(plainTextBytes,0,decryptptedByteCount);
}
}
}
}
catch(CryptographicException异常)
{
plainText = string.Empty; //假设错误是由无效密码造成的
}

return plainText;
}

public string Encrypt(string plainText)
{
string encryptedText;
byte [] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC};

using(ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(_KeyBytes,_InitVectorBytes))
{
using(MemoryStream memoryStream = new MemoryStream())
{
使用(CryptoStream cryptoStream = new CryptoStream(memoryStream,encryptor,CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes,0,plainTextBytes.Length);
cryptoStream.FlushFinalBlock();

byte [] cipherTextBytes = memoryStream.ToArray();
encryptedText = Convert.ToBase64String(cipherTextBytes);
}
}
}

return encryptedText;
}
}


I am trying to encrypt/decrypt an XML file. I found this sample for encrypting but I do not know how to decrypt? Any idea? Thanks!

        // Load this XML file
        System.Xml.XmlDocument myDoc = new System.Xml.XmlDocument();
        myDoc.Load(@"c:\persons.xml");
        // Get a specified element to be encrypted
        System.Xml.XmlElement element = myDoc.GetElementsByTagName("Persons")[0] as System.Xml.XmlElement;

        // Create a new TripleDES key. 
        System.Security.Cryptography.TripleDESCryptoServiceProvider tDESkey = new System.Security.Cryptography.TripleDESCryptoServiceProvider();

        // Form a Encrypted XML with the Key
        System.Security.Cryptography.Xml.EncryptedXml encr = new System.Security.Cryptography.Xml.EncryptedXml();
        encr.AddKeyNameMapping("Deskey", tDESkey);

        // Encrypt the element data
        System.Security.Cryptography.Xml.EncryptedData ed = encr.Encrypt(element, "Deskey");

        // Replace the existing data with the encrypted data
        System.Security.Cryptography.Xml.EncryptedXml.ReplaceElement(element, ed, false);

        // saves the xml file with encrypted data
        myDoc.Save(@"c:\encryptedpersons.xml");

But I do not know how I would decrypt that? Any ideas? Thanks!

解决方案

Something like this:

public static class Encryption
{
    private const string InitVector = "T=A4rAzu94ez-dra";
    private const int KeySize = 256;
    private const int PasswordIterations = 1000; //2;
    private const string SaltValue = "d=?ustAF=UstenAr3B@pRu8=ner5sW&h59_Xe9P2za-eFr2fa&ePHE@ras!a+uc@";

    public static string Decrypt(string encryptedText, string passPhrase)
    {
        byte[] encryptedTextBytes = Convert.FromBase64String(encryptedText);
        byte[] initVectorBytes = Encoding.UTF8.GetBytes(InitVector);
        byte[] passwordBytes = Encoding.UTF8.GetBytes(passPhrase);
        string plainText;
        byte[] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue);

        Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passwordBytes, saltValueBytes, PasswordIterations);
        byte[] keyBytes = password.GetBytes(KeySize / 8);

        RijndaelManaged rijndaelManaged = new RijndaelManaged { Mode = CipherMode.CBC };

        try
        {
            using (ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(keyBytes, initVectorBytes))
            {
                using (MemoryStream memoryStream = new MemoryStream(encryptedTextBytes))
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        //TODO: Need to look into this more. Assuming encrypted text is longer than plain but there is probably a better way
                        byte[] plainTextBytes = new byte[encryptedTextBytes.Length];

                        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                        plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                    }
                }
            }
        }
        catch (CryptographicException)
        {
            plainText = string.Empty; // Assume the error is caused by an invalid password
        }

        return plainText;
    }

    public static string Encrypt(string plainText, string passPhrase)
    {
        string encryptedText;
        byte[] initVectorBytes = Encoding.UTF8.GetBytes(InitVector);
        byte[] passwordBytes = Encoding.UTF8.GetBytes(passPhrase);
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue);

        Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passwordBytes, saltValueBytes, PasswordIterations);
        byte[] keyBytes = password.GetBytes(KeySize / 8);

        RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC};

        using (ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(keyBytes, initVectorBytes))
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                    cryptoStream.FlushFinalBlock();

                    byte[] cipherTextBytes = memoryStream.ToArray();
                    encryptedText = Convert.ToBase64String(cipherTextBytes);
                }
            }
        }

        return encryptedText;
    }
}

Edit:

Sani Huttunen pointed out that my static implementation above has a severe performance issue if you will be encrypting multiple pieces of data using the same password. You can read more about it here: http://jmpstart.wordpress.com/2009/09/29/proper-use-of-rfc2898derivebytes/

Edit: A non-static implementation that is much more efficient if you need to perform multiple encryptions/decryptions using the same password (~32ms original ~1ms new).

public class SimpleEncryption
{
    #region Constructor
    public SimpleEncryption(string password)
    {
        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
        byte[] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue);

        _DeriveBytes = new Rfc2898DeriveBytes(passwordBytes, saltValueBytes, PasswordIterations);
        _InitVectorBytes = Encoding.UTF8.GetBytes(InitVector);
        _KeyBytes = _DeriveBytes.GetBytes(32);
    }
    #endregion

    #region Private Fields
    private readonly Rfc2898DeriveBytes _DeriveBytes;
    private readonly byte[] _InitVectorBytes;
    private readonly byte[] _KeyBytes;
    #endregion

    private const string InitVector = "T=A4rAzu94ez-dra";
    private const int PasswordIterations = 1000; //2;
    private const string SaltValue = "d=?ustAF=UstenAr3B@pRu8=ner5sW&h59_Xe9P2za-eFr2fa&ePHE@ras!a+uc@";

    public string Decrypt(string encryptedText)
    {
        byte[] encryptedTextBytes = Convert.FromBase64String(encryptedText);
        string plainText;

        RijndaelManaged rijndaelManaged = new RijndaelManaged { Mode = CipherMode.CBC };

        try
        {
            using (ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(_KeyBytes, _InitVectorBytes))
            {
                using (MemoryStream memoryStream = new MemoryStream(encryptedTextBytes))
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        //TODO: Need to look into this more. Assuming encrypted text is longer than plain but there is probably a better way
                        byte[] plainTextBytes = new byte[encryptedTextBytes.Length];

                        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                        plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                    }
                }
            }
        }
        catch (CryptographicException exception)
        {
            plainText = string.Empty; // Assume the error is caused by an invalid password
        }

        return plainText;
    }

    public string Encrypt(string plainText)
    {
        string encryptedText;
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC};

        using (ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(_KeyBytes, _InitVectorBytes))
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                    cryptoStream.FlushFinalBlock();

                    byte[] cipherTextBytes = memoryStream.ToArray();
                    encryptedText = Convert.ToBase64String(cipherTextBytes);
                }
            }
        }

        return encryptedText;
    }
}

这篇关于如何加密/解密XML文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆