我需要两个方法来加密,一个用密钥="hello world"来解密xml文件,密钥hello world应该用于加密和解密xml文件.这些方法应该适用于所有机器!任何加密方法都可以.XML文件内容如下:
<root>
<lic>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</lic>
</root>
Run Code Online (Sandbox Code Playgroud)
有些人可以给我一个示例吗?问题是msdn示例encyptions使xml文件被加密但是当我在另一台机器上解密时它不起作用.例如
我尝试了这个示例: 如何:使用非对称密钥加密XML元素,但这里有一些有点会话,而在另一台机器上它说坏数据phewf!
Kob*_*obi 14
如果你想要加密和解密的相同密钥,你应该使用对称方法(这就是定义,真的).这是与您的样本最接近的一个(相同的来源). 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);
Run Code Online (Sandbox Code Playgroud)
现在程序使用相同的密钥和初始向量,加密和解密应该适用于所有计算机.
另外,考虑重新命名key来algorithm,否则这是非常误导的.我会说这是来自MSDN的一个糟糕的,不好用的例子.
注意:PasswordDeriveBytes.GetBytes()由于类中存在严重(安全)问题而被弃用PasswordDeriveBytes.上面的代码已被重写为使用更安全的Rfc2898DeriveBytes类(PBKDF2而不是PBKDF1).使用上述使用生成的代码PasswordDeriveBytes可能会受到影响.
首先,如果你想使用相同的密钥进行加密和解密,你应该看看对称密码学。非对称加密是指加密和解密的密钥不同。只是为了让您知道 - RSA 是非对称的,TripleDES 和 Rijndael 是对称的。还有其他的,但 .NET 没有它们的默认实现。
我建议学习System.Security.Cryptography namespace. 并学习一些关于所有这些东西的知识。它拥有加密和解密文件以及生成密码所需的一切。特别是,您可能对这些类感兴趣:
CryptoStreamPasswordDeriveBytesRijndaelManaged在 MSDN 中也有使用示例。您可以使用这些类来加密任何文件,而不仅仅是 XML。但是,如果您只想加密选定的几个元素,则可以查看System.Security.Cryptography.Xml命名空间。我看到你已经找到了一篇关于它的文章。继续点击该页面上的链接,您将了解有关这些课程的更多信息。
如果您使用私钥对<lic>元素签名并将结果添加到文件(也许在<hash>元素中),效果会更好。如果您的支持人员需要知道许可证号或有效期,这将使每个人都可以读取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()); }
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24430 次 |
| 最近记录: |