我需要两个方法来加密,一个用密钥=“hello world”来解密xml文件,密钥hello world应该用于加密和解密xml文件。这些方法应该适用于所有机器! !任何加密方法都可以。 XML文件内容如下:
<root>
<lic>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</lic>
</root>
有些人可以给我一个示例吗?问题是msdn示例encyptions使得xml文件被加密但是当我在另一台机器上解密时它不起作用。例如
我试过这个样本: How to: Encrypt XML Elements with Asymmetric Keys, 但这里有一些有点会话,在另一台机器上,它说坏数据phewf!
答案 0 :(得分:13)
如果你想要相同的密钥进行加密和解密,你应该使用对称方法(这就是定义,真的)。这是与您的样本最接近的一个(相同的来源)。 http://msdn.microsoft.com/en-us/library/sb7w85t6.aspx
发布的示例无效,因为他们没有使用相同的密钥。不仅在不同的机器上:在同一台机器上运行两次程序也不应该工作(对我来说不起作用),因为它们每次都使用不同的随机键。
尝试在创建密钥后添加此代码:
key = new RijndaelManaged();
string password = "Password1234"; //password here
byte[] saltBytes = Encoding.UTF8.GetBytes("Salt"); // salt here (another string)
var p = new Rfc2898DeriveBytes(password, saltBytes); //TODO: think about number of iterations (third parameter)
// sizes are devided by 8 because [ 1 byte = 8 bits ]
key.IV = p.GetBytes(key.BlockSize / 8);
key.Key = p.GetBytes(key.KeySize / 8);
现在程序使用相同的密钥和初始向量,加密和解密应该适用于所有计算机
另外,请考虑将key
重命名为algorithm
,否则这会产生误导。我说这是来自MSDN的一个糟糕的,不好用的例子。
<子>
注意:PasswordDeriveBytes.GetBytes()
由于PasswordDeriveBytes
类中的严重(安全)问题而被弃用。上面的代码已被重写为使用更安全的Rfc2898DeriveBytes
类(PBKDF2而不是PBKDF1)。上述使用PasswordDeriveBytes
生成的代码可能会受到影响
子>
答案 1 :(得分:4)
如果您使用私钥对&lt; lic&gt;进行签名,会更酷吗? element并将结果添加到文件中(可能在&lt; hash&gt;元素中)。如果您的支持需要知道许可证编号或到期日期,这将使每个人都可以阅读xml文件,但如果没有私钥,他们就无法更改任何值。
验证签名所需的公钥是常识。
<强>澄清强>
对代码进行签名只会保护代码免受更改,并且不会隐藏其中的任何信息。您的原始问题提到加密,但我不确定是否需要隐藏数据,或者只是保护数据不被修改。
示例代码:(从不发布PrivateKey.key。只有在签署xml文件时才需要ServerMethods,只有在验证xml文件时才需要ClientMethods。)
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
public static class Program {
public static void Main() {
if (!File.Exists("PublicKey.key")) {
// Assume first run, generate keys and sign document.
ServerMethods.GenerateKeyPair();
var input = new XmlDocument();
input.Load("input.xml");
Debug.Assert(input.DocumentElement != null);
var licNode = input.DocumentElement["lic"];
Debug.Assert(licNode != null);
var licNodeXml = licNode.OuterXml;
var signedNode = input.CreateElement("signature");
signedNode.InnerText = ServerMethods.CalculateSignature(licNodeXml);
input.DocumentElement.AppendChild(signedNode);
input.Save("output.xml");
}
if (ClientMethods.IsValidLicense("output.xml")) {
Console.WriteLine("VALID");
} else {
Console.WriteLine("INVALID");
}
}
public static class ServerMethods {
public static void GenerateKeyPair() {
var rsa = SharedInformation.CryptoProvider;
using (var keyWriter = File.CreateText("PublicKey.key"))
keyWriter.Write(rsa.ToXmlString(false));
using (var keyWriter = File.CreateText("PrivateKey.key"))
keyWriter.Write(rsa.ToXmlString(true));
}
public static string CalculateSignature(string data) {
var rsa = SharedInformation.CryptoProvider;
rsa.FromXmlString(File.ReadAllText("PrivateKey.key"));
var dataBytes = Encoding.UTF8.GetBytes(data);
var signatureBytes = rsa.SignData(dataBytes, SharedInformation.HashAlgorithm);
return Convert.ToBase64String(signatureBytes);
}
}
public static class ClientMethods {
public static bool IsValid(string data, string signature) {
var rsa = SharedInformation.CryptoProvider;
rsa.FromXmlString(File.ReadAllText("PublicKey.key"));
var dataBytes = Encoding.UTF8.GetBytes(data);
var signatureBytes = Convert.FromBase64String(signature);
return rsa.VerifyData(dataBytes, SharedInformation.HashAlgorithm, signatureBytes);
}
public static bool IsValidLicense(string filename) {
var doc = new XmlDocument();
doc.Load(filename);
var licNode = doc.SelectSingleNode("/root/lic") as XmlElement;
var signatureNode = doc.SelectSingleNode("/root/signature") as XmlElement;
if (licNode == null || signatureNode == null) return false;
return IsValid(licNode.OuterXml, signatureNode.InnerText);
}
}
public static class SharedInformation {
public static int KeySize {
get { return 1024; }
}
public static string HashAlgorithm {
get { return "SHA512"; }
}
public static RSACryptoServiceProvider CryptoProvider {
get { return new RSACryptoServiceProvider(KeySize, new CspParameters()); }
}
}
}
答案 2 :(得分:3)
首先,如果要使用相同的密钥进行加密和解密,则应查看对称加密。非对称加密是指用于加密和解密的密钥不同的时候。只是让你知道 - RSA是不对称的,TripleDES和Rijndael是对称的。还有其他一些,但.NET没有默认的实现。
我建议研究System.Security.Cryptography namespace
。并学习一点所有的东西。它拥有加密和解密文件以及生成密码所需的一切。特别是,您可能对这些类感兴趣:
CryptoStream
PasswordDeriveBytes
RijndaelManaged
在MSDN中也有使用它们的示例。您可以使用这些类来加密任何文件,而不仅仅是XML。但是,如果您只想加密少数几个元素,可以查看System.Security.Cryptography.Xml
命名空间。我看到你已经找到了一篇关于它的文章。请继续关注该页面上的链接,您将了解有关这些课程的更多信息。
答案 3 :(得分:2)
这是您对XML文档进行数字签名和验证的方式Sign XML Documents