C# xml 常规 保护 方法总结
2013-07-06 17:37
288 查看
一 使用xsd模式文件验证xml文件:
xml文件:
xsd文件:
验证代码:
调用代码:
string xmlPath = "books.xml";
string xsd = "books.xsd";
string message = string.Empty;
bool validate = XmlValidate(xmlPath, xsd, out message);
二xml查询时需要注意XQuery注入(XPath注入),通常xPath语句如下:
但是这样的代码很容易遭到攻击,这里我们用Mvp.xml(开源库http://mvpxml.codeplex.com/)来实现参数化查询,防止xquery注入。
修改后的代码:
采用对称加密,加密xml节点新建xml文件如下:
加密和解密代码如下:
调用方法如下:
string xmlPath = "encrypt.xml";
XmlDocument document = new XmlDocument();
document.Load(xmlPath);
RijndaelManaged rijndael = new RijndaelManaged();
Encrypt(document, "message", rijndael);
Decrypt(document, rijndael);
加密后的数据如图:
View Code
调用代码如下:
string xmlPath = "encrypt.xml";
XmlDocument document = new XmlDocument();
document.PreserveWhitespace = true;
document.Load(xmlPath);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
SignXml(document, rsa);
IsSignedXmlValid(document, rsa);
运行结果如图:
个人认为证书在xml中使用情况不常见,并且也比较简单,这里就省略了。
总结一下:
在使用xml之前,必须使用严格的架构(模式文件)来验证,尽可能使用架构的本地副本,以便缓存解析器来缓存他们。
选择一个合适的加密算法,如果应用程序需要加密和解密相同的应用程序,那么选择对称加密;应用程序需要和外部系统进行交流,那么选择非对称加密。
如果需要确保数据没有被更改,就需要始终使用数字签名
xml文件:
<?xml version="1.0" encoding="utf-8" ?> <Books> <Book> <Title>ExampleTitle</Title> <Author>John Smith</Author> <Pages>500</Pages> </Book> <Book> <Title>Another Title</Title> <Author>John Doe</Author> <Pages>250</Pages> </Book> </Books>
xsd文件:
<?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Books"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="Book"> <xs:complexType> <xs:sequence> <xs:element name="Title" type="xs:string" minOccurs="1" maxOccurs="1" /> <xs:element name="Author" type="xs:string" /> <xs:element name="Pages" type="xs:unsignedShort" minOccurs="1" maxOccurs="1" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
验证代码:
static bool XmlValidate(string xmlPath, string xsdPath, out string message) { bool isXmlValid = true; string errorMessage = string.Empty; XmlReaderSettings settings = new XmlReaderSettings() { ValidationType = ValidationType.Schema, ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings }; settings.ValidationEventHandler += (o, e) => { isXmlValid = false; errorMessage = e.Message; }; XmlSchema schema = XmlSchema.Read(new StreamReader(xsdPath), null); settings.Schemas.Add(schema); XmlDocument xmlDocument = new XmlDocument(); XmlReader xmlReader = XmlReader.Create(xmlPath, settings); xmlDocument.Load(xmlReader); message = errorMessage; return isXmlValid; }
调用代码:
string xmlPath = "books.xml";
string xsd = "books.xsd";
string message = string.Empty;
bool validate = XmlValidate(xmlPath, xsd, out message);
二xml查询时需要注意XQuery注入(XPath注入),通常xPath语句如下:
static string GetBookTitle(string author, int page) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load("books.xml"); XPathNavigator navigator = xmlDocument.CreateNavigator(); string xquery = string.Format("string(//Book[Author/text()='{0}' and Pages/text()={1}]/Title/text())", author, page.ToString()); XPathExpression expression = navigator.Compile(xquery); return navigator.Evaluate(expression).ToString(); }
但是这样的代码很容易遭到攻击,这里我们用Mvp.xml(开源库http://mvpxml.codeplex.com/)来实现参数化查询,防止xquery注入。
修改后的代码:
static string GetBookTitle(string author, int page) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load("books.xml"); string xquery = "string(//Book[Author/text()=$author and Pages/text()=$page]/Title/text())"; XPathNavigator navigator = xmlDocument.CreateNavigator(); XPathExpression expression = DynamicContext.Compile(xquery); DynamicContext ctx = new DynamicContext(); ctx.AddVariable("author", author); ctx.AddVariable("page",page.ToString()); expression.SetContext(ctx); return navigator.Evaluate(expression).ToString(); }
采用对称加密,加密xml节点新建xml文件如下:
<?xml version="1.0" encoding="utf-8" ?> <envelope> <to>ma.jiang@wipro.com</to> <from>gavin_ma@vfc.com</from> <message>You have just been paid.</message> </envelope>
加密和解密代码如下:
static void Encrypt(XmlDocument document, string elementNameToEntrypt, SymmetricAlgorithm algorithm) { if (document == null) throw new ArgumentNullException("document"); if (elementNameToEntrypt == null) throw new ArgumentNullException("elementNameToEntrypt"); if (algorithm == null) throw new ArgumentNullException("key"); XmlElement elementToEncrypt = document.GetElementsByTagName(elementNameToEntrypt)[0] as XmlElement; if (elementToEncrypt == null) throw new XmlException("The specified element was not found"); EncryptedXml exml = new EncryptedXml(); byte[] encryptedElement = exml.EncryptData(elementToEncrypt, algorithm, false); EncryptedData encryptedData = new EncryptedData { Type = EncryptedXml.XmlEncElementUrl }; string encryptionMethod = string.Empty; if (algorithm is TripleDES) encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; else if (algorithm is DES) encryptionMethod = EncryptedXml.XmlEncDESUrl; else if (algorithm is Rijndael) { switch (algorithm.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { throw new CryptographicException("Specificed algorithm is not supported"); } encryptedData.EncryptionMethod = new EncryptionMethod(encryptionMethod); encryptedData.CipherData.CipherValue = encryptedElement; EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); } static void Decrypt(XmlDocument document, SymmetricAlgorithm algorithm) { if (document == null) throw new ArgumentNullException("document"); if (algorithm == null) throw new ArgumentNullException("key"); XmlElement encryptedElement = document.GetElementsByTagName("EncryptedData")[0] as XmlElement; if (encryptedElement == null) throw new XmlException("No encrypted element was found."); EncryptedData encryptedData = new EncryptedData(); encryptedData.LoadXml(encryptedElement); EncryptedXml encryptedXml = new EncryptedXml(); byte[] rgbOutput = encryptedXml.DecryptData(encryptedData, algorithm); encryptedXml.ReplaceData(encryptedElement,rgbOutput); }
调用方法如下:
string xmlPath = "encrypt.xml";
XmlDocument document = new XmlDocument();
document.Load(xmlPath);
RijndaelManaged rijndael = new RijndaelManaged();
Encrypt(document, "message", rijndael);
Decrypt(document, rijndael);
加密后的数据如图:
static void SignXml(XmlDocument document, RSA algorithm) { SignedXml signxml = new SignedXml(document) { SigningKey = algorithm }; Reference reference = new Reference { Uri = string.Empty }; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signxml.AddReference(reference); signxml.ComputeSignature(); XmlElement xmlDigitalSignature = signxml.GetXml(); document.DocumentElement.AppendChild(document.ImportNode(xmlDigitalSignature,true)); } static bool IsSignedXmlValid(XmlDocument document, RSA algorithm) { SignedXml signxml = new SignedXml(document); XmlNodeList nodelist = document.GetElementsByTagName("Signature"); if (nodelist.Count < 1) { throw new CryptographicException("No signature found"); } signxml.LoadXml((XmlElement)nodelist[0]); return signxml.CheckSignature(algorithm); }
View Code
调用代码如下:
string xmlPath = "encrypt.xml";
XmlDocument document = new XmlDocument();
document.PreserveWhitespace = true;
document.Load(xmlPath);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
SignXml(document, rsa);
IsSignedXmlValid(document, rsa);
运行结果如图:
个人认为证书在xml中使用情况不常见,并且也比较简单,这里就省略了。
总结一下:
在使用xml之前,必须使用严格的架构(模式文件)来验证,尽可能使用架构的本地副本,以便缓存解析器来缓存他们。
选择一个合适的加密算法,如果应用程序需要加密和解密相同的应用程序,那么选择对称加密;应用程序需要和外部系统进行交流,那么选择非对称加密。
如果需要确保数据没有被更改,就需要始终使用数字签名
相关文章推荐
- C# xml 常规 保护 方法总结
- C#.NET示例读写xml所有节点的代码实现方法和读取xml节点的数据总结
- C#.NET示例读写xml所有节点的代码实现方法和读取xml节点的数据总结
- C# 在.net中序列化读写xml方法的总结
- C# XML序列化方法及常用特性总结分析
- ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 用javascript在客户端删除某一个cookie键值对 input点击链接另一个页面,各种操作。 C# 往线程里传参数的方法总结 TCP/IP 协议 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图 (转)值得学习百度开源70+项目
- C#操作XML的通用方法总结
- C#.NET示例读写xml所有节点的代码实现方法和读取xml节点的数据总结
- c#典型排序方法总结
- C#导出数据到Excel中方法总结
- SpringMVC上传图片总结(1)-Web Uploader--常规方法进行图片上传,使用了MultipartFile、MultipartHttpServletRequest
- C#学习笔记(12)——三种方法操作XML
- C#发送Email邮件方法总结
- C#下 读取xml节点的数据总结
- 总结C#获取当前路径的7种方法
- C#操作XML的方法
- .NET(C#):XmlReader和Whitespace以及MoveToContent和ReadToFollowing方法
- RSS制作(C#) - 使用XML DOM和XmlTextWriter(见评论)两种方法
- C# 对XML基本操作代码总结
- 在C#.net中操作XML的基本方法