我正在尝试学习.NET API,并且我创建了一个程序,用于将源文件中的密钥与XML文件中的密钥进行比较。
我使用了以下exaple(第三种方法来修改文档:
现在我的程序运行但它总是说文件已被篡改,即使我完全确定它们不是因为我刚创建它们。
这是我的代码:
VerifyDocument.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Xml.Serialization;
public class VerifyDocument
{
public static void Main(string[] args)
{
XmlSerializer xml = new XmlSerializer(typeof(byte[]));
byte[] key;
string keyFile = args[1];
string sourceFile = args[0];
using (StreamReader reader = new StreamReader(keyFile)) {
key = (byte[]) xml.Deserialize(reader);
}
bool err = false;
using (HMACSHA256 hmac = new HMACSHA256(key)) // Initialize the keyed hash object.
{
byte[] storedHash = new byte[hmac.HashSize / 8]; // Create an array to hold the keyed hash value read from the file.
using (FileStream inStream = new FileStream(sourceFile, FileMode.Open)) // Create a FileStream for the source file.
{
inStream.Read(storedHash, 0, storedHash.Length); // Read in the storedHash.
byte[] computedHash = hmac.ComputeHash(inStream);
// compare the computed hash with the stored value
for (int i = 0; i < storedHash.Length; i++)
{
if (computedHash[i] != storedHash[i])
{
err = true;
}
}
}
}
if (err)
{
Console.WriteLine("Hash values differ! Signed file has been tampered with!");
}
else
{
Console.WriteLine("Hash values agree -- no tampering occurred.");
}
}
}
SignDocument.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Xml.Serialization;
public class HMACSHA256example
{
public static void Main(string[] args)
{
if (args.Length != 2) {
Console.WriteLine("Usage: [mono] SignDocument.exe <filename> <key>");
Environment.Exit(1);
} else
{
XmlSerializer xml = new XmlSerializer(typeof(byte[]));
byte[] key;
string keyFile = args[1];
string sourceFile = args[0];
string destFile = sourceFile + ".hash";
using (StreamReader reader = new StreamReader(keyFile)) {
key = (byte[]) xml.Deserialize(reader);
}
using (HMACSHA256 hmac = new HMACSHA256(key)) // Initialize the keyed hash object.
{
using (FileStream inStream = new FileStream(sourceFile, FileMode.Open))
{
using (FileStream outStream = new FileStream(destFile, FileMode.Create))
{
byte[] hashValue = hmac.ComputeHash(inStream); // Compute the hash of the input file.
outStream.Write(hashValue, 0, hashValue.Length); // Write the computed hash value to the output file.
}
}
}
}
}
}
CreateKey.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Xml.Serialization;
namespace COMP3911.Crypto {
class CreateKey {
static void Main(string[] args) {
string input;
if (args.Length == 0) {
Console.WriteLine("Usage: [mono] CreateKey.exe <filename>");
Environment.Exit(1);
}
byte[] secretkey = new Byte[64];
//RNGCryptoServiceProvider is an implementation of a random number generator.
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
// The array is now filled with cryptographically strong random bytes.
rng.GetBytes(secretkey);
}
// XML
string keyfile = args[0] + ".key";
using (StreamWriter output = new StreamWriter(keyfile, false)) {
XmlSerializer xml = new XmlSerializer(typeof(byte[]));
xml.Serialize(output, secretkey);
}
}
}
}
非常感谢任何帮助!
答案 0 :(得分:0)
您的&#34;签署&#34;程序读取inStream
并仅将HMAC写入outStream
。
你的&#34;验证&#34;程序读取一个文件,并期望它是HMAC,然后是数据。
&#34;签署&#34;需要快退inStream
,然后将其复制到outStream
,或者您需要更改&#34;验证&#34;单独查看这两个文件。
答案 1 :(得分:0)
SignDocument.cs
有错误。您正在编写签名但未能写入文件的其余部分。
它应该是这样的(大多数是从链接到的文档页面复制的):
using (HMACSHA256 hmac = new HMACSHA256(key)) // Initialize the keyed hash object.
{
using (FileStream inStream = new FileStream(sourceFile, FileMode.Open))
{
using (FileStream outStream = new FileStream(destFile, FileMode.Create))
{
byte[] hashValue = hmac.ComputeHash(inStream); // Compute the hash of the input file.
outStream.Write(hashValue, 0, hashValue.Length); // Write the computed hash value to the output file.
inStream.Position = 0;
int bytesRead;
byte[] buffer = new byte[1024];
do
{
bytesRead = inStream.Read(buffer, 0, 1024);
outStream.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
}
}
}
<强>更新强>
不确定为什么MSDN版本不使用CopyTo
,但似乎更好:
byte[] hashValue = hmac.ComputeHash(inStream);
outStream.Write(hashValue, 0, hashValue.Length);
inStream.Position = 0;
inStream.CopyTo(outStream);