[原创] 不仅拥有XmlDocument一样简单的XML操作方法,并且实现数据文件安全存储功能——XmlEDocument
与NParsing框架无关,继续“甜品”
在C/S结构的系统中,如果在客户端登录对话框中,需要记录所有在当前机器上登录过的用户名、密码和一些其它信息时,是一件让
人头疼的事情。因为要考虑记录信息的安全性。不能随随便便把密码和一些重要信息给放在明码的配置文件中。
类似QQ登录窗口的帐号输入框,这种数据的本地存储
可能人有会说,那我可以把这些重要信息加密啊,对!!!就是加密。但是你把一项一项加密会不会觉得很繁琐。如果单单是一个
密码,一个用户信息到也还好。那要是系统中有很多都要加密呢?你看我们最常用的QQ,保存在客户端中的所有信息几乎都是加密的(
软件目录里有很多.dat文件),比如用户信息?聊天记录啊?一些配置啊?一些设置啊?先不管它是怎么实现的。我来讲讲我的思路和
我在C#中是怎么实现简单又好用的XmlEDocument的。
我是这样想的,可以把要考虑安全性因素的信息以XML的格式写入内存流中(因为XML操作非常方便),再把整个内存流中加密,保
存成文件(扩展名就无谓了,可以不用.xml,你可以用.dat、.db显得专业点,哈哈)。想到这里,就开始动手,为了提高代码的重用率
,把XmlDocument自己封装一下,取名XmlEDocument。
其实实现超简单,下面看代码吧:
代码
1 using System.Collections.Generic;
2 using System.IO;
3 using System.Security.Cryptography;
4 using System.Text;
5 using System.Xml;
6
7 namespace DotNet.Common
8 {
9 public class XmlEDocument : XmlDocument
10 {
11 private const string ENCR_KEY = "zhuxiaoc";
12 private const int READ_SIZE = 16*1024;
13
14 public override void Load(string filename)
15 {
16 var fileStream = new FileStream(filename, FileMode.Open);
17 Load(fileStream);
18 }
19
20 public override void Load(Stream inStream)
21 {
22 var bsXml = new List<byte>();
23 var b = new byte[READ_SIZE];
24 int iLength;
25 while ((iLength = inStream.Read(b, 0, READ_SIZE)) > 0)
26 {
27 for (int i = 0; i < iLength; i++)
28 {
29 bsXml.Add(b[i]);
30 }
31 }
32 inStream.Close();
33 var msEXml = new MemoryStream();
34 var des = new DESCryptoServiceProvider();
35 byte[] byKey = Encoding.UTF8.GetBytes(ENCR_KEY.Substring(0, 8));
36 byte[] IV = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
37 var cs = new CryptoStream(msEXml, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);
38 cs.Write(bsXml.ToArray(), 0, bsXml.ToArray().Length);
39 cs.FlushFinalBlock();
40 base.Load(new MemoryStream(msEXml.ToArray()));
41 }
42
43 public override void Save(string filename)
44 {
45 if(!File.Exists(filename))
46 File.Create(filename).Close();
47
48 var fileStream = new FileStream(filename, FileMode.Truncate);
49 Save(fileStream);
50 fileStream.Close();
51 }
52
53 public override void Save(Stream outStream)
54 {
55 var msXml = new MemoryStream();
56 base.Save(msXml);
57 var des = new DESCryptoServiceProvider();
58 byte[] byKey = Encoding.UTF8.GetBytes(ENCR_KEY.Substring(0, 8));
59 byte[] IV = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
60 var cs = new CryptoStream(outStream, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);
61 cs.Write(msXml.ToArray(), 0, msXml.ToArray().Length);
62 cs.FlushFinalBlock();
63 msXml.Close();
64 }
65 }
66 }
2 using System.IO;
3 using System.Security.Cryptography;
4 using System.Text;
5 using System.Xml;
6
7 namespace DotNet.Common
8 {
9 public class XmlEDocument : XmlDocument
10 {
11 private const string ENCR_KEY = "zhuxiaoc";
12 private const int READ_SIZE = 16*1024;
13
14 public override void Load(string filename)
15 {
16 var fileStream = new FileStream(filename, FileMode.Open);
17 Load(fileStream);
18 }
19
20 public override void Load(Stream inStream)
21 {
22 var bsXml = new List<byte>();
23 var b = new byte[READ_SIZE];
24 int iLength;
25 while ((iLength = inStream.Read(b, 0, READ_SIZE)) > 0)
26 {
27 for (int i = 0; i < iLength; i++)
28 {
29 bsXml.Add(b[i]);
30 }
31 }
32 inStream.Close();
33 var msEXml = new MemoryStream();
34 var des = new DESCryptoServiceProvider();
35 byte[] byKey = Encoding.UTF8.GetBytes(ENCR_KEY.Substring(0, 8));
36 byte[] IV = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
37 var cs = new CryptoStream(msEXml, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);
38 cs.Write(bsXml.ToArray(), 0, bsXml.ToArray().Length);
39 cs.FlushFinalBlock();
40 base.Load(new MemoryStream(msEXml.ToArray()));
41 }
42
43 public override void Save(string filename)
44 {
45 if(!File.Exists(filename))
46 File.Create(filename).Close();
47
48 var fileStream = new FileStream(filename, FileMode.Truncate);
49 Save(fileStream);
50 fileStream.Close();
51 }
52
53 public override void Save(Stream outStream)
54 {
55 var msXml = new MemoryStream();
56 base.Save(msXml);
57 var des = new DESCryptoServiceProvider();
58 byte[] byKey = Encoding.UTF8.GetBytes(ENCR_KEY.Substring(0, 8));
59 byte[] IV = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
60 var cs = new CryptoStream(outStream, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);
61 cs.Write(msXml.ToArray(), 0, msXml.ToArray().Length);
62 cs.FlushFinalBlock();
63 msXml.Close();
64 }
65 }
66 }
这就不要注释了吧,直接拿去用就好了。如果嫌加密方法不好,你就把加密代码改改吧。
写个简单的例子吧:
这是创建XML
代码
1 var xmlDocument = new XmlDocument();
2 var dec = xmlDocument.CreateXmlDeclaration("1.0", "utf-8", null);
3 xmlDocument.AppendChild(dec);
4 var root = xmlDocument.CreateElement("Users");
5 xmlDocument.AppendChild(root);
6 xmlDocument.Save("c:\\test.xml");
2 var dec = xmlDocument.CreateXmlDeclaration("1.0", "utf-8", null);
3 xmlDocument.AppendChild(dec);
4 var root = xmlDocument.CreateElement("Users");
5 xmlDocument.AppendChild(root);
6 xmlDocument.Save("c:\\test.xml");
这是创建加密的XML
代码
1 var xmlEDocument = new XmlEDocument();
2 var dec = xmlEDocument.CreateXmlDeclaration("1.0", "utf-8", null);
3 xmlEDocument.AppendChild(dec);
4 var root = xmlEDocument.CreateElement("Users");
5 xmlEDocument.AppendChild(root);
6 xmlEDocument.Save("c:\\test.dat");
2 var dec = xmlEDocument.CreateXmlDeclaration("1.0", "utf-8", null);
3 xmlEDocument.AppendChild(dec);
4 var root = xmlEDocument.CreateElement("Users");
5 xmlEDocument.AppendChild(root);
6 xmlEDocument.Save("c:\\test.dat");
代码写法完全一样,达到效果确是完全不同。