/// <summary>
/// 解密文件
/// </summary>
/// <param name="inFile">待解密文件</param>
/// <param name="outFile">解密后输出文件</param>
/// <param name="password">解密密码</param>
public static void DecryptFile(string inFile, string outPath, string password)
{
try
{
int outValue = 0;
long lSize = -1;
byte[] oldHash = null;
byte[] curHash = null;
int read = -1;
// 创建打开文件流
using (FileStream fin = File.OpenRead(inFile))
{
int size = (int)fin.Length;
byte[] bytes = new byte[BUFFER_SIZE];
int value = 0;
int len = fin.ReadByte();
byte[] tem1 = new byte[len];
fin.Read(tem1, 0, tem1.Length);
int len2 = System.BitConverter.ToInt32(tem1, 0);
byte[] tem2 = new byte[len2];
fin.Read(tem2, 0, tem2.Length);
String filename = Encoding.UTF8.GetString(tem2);
String outFile = Path.Combine(outPath, filename);
byte[] IV = new byte[16];
fin.Read(IV, 0, 16);
byte[] salt = new byte[16];
fin.Read(salt, 0, 16);
SymmetricAlgorithm sma = Common.CreateRijndael(password, salt);
sma.IV = IV;
value = 32;
// 创建散列对象, 校验文件
HashAlgorithm hasher = SHA256.Create();
using (FileStream fout = File.OpenWrite(outFile))
{
using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read),
chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
{
// 读取文件长度
BinaryReader br = new BinaryReader(cin);
lSize = br.ReadInt64();
ulong tag = br.ReadUInt64();
if (FC_TAG != tag)
throw new CryptoHelpException("文件被破坏");
long numReads = lSize / BUFFER_SIZE;
long slack = (long)lSize % BUFFER_SIZE;
for (int i = 0; i < numReads; ++i)
{
read = cin.Read(bytes, 0, bytes.Length);
fout.Write(bytes, 0, read);
chash.Write(bytes, 0, read);
value += read;
outValue += read;
}
if (slack > 0)
{
read = cin.Read(bytes, 0, (int)slack);
fout.Write(bytes, 0, read);
chash.Write(bytes, 0, read);
value += read;
outValue += read;
}
chash.Flush();
chash.Close();
fout.Flush();
fout.Close();
curHash = hasher.Hash;
// 获取比较和旧的散列对象
oldHash = new byte[hasher.HashSize / 8];
read = cin.Read(oldHash, 0, oldHash.Length);
}
}
}
if (outValue != lSize)
{
throw new CryptoHelpException("文件大小不匹配");
}
if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash)))
{
throw new CryptoHelpException("文件被破坏");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
这段代码主要做了3个事情
1.首先是校验文件
2.是获取原始文件名称
3.解密文件成原始文件
提供完成的C#实现为文件加解密工具:
该代码段展示了一个使用C#编写的文件解密方法,它首先校验文件完整性,然后读取并解密文件内容,最后对比散列值确保解密后的文件未被篡改。过程中涉及了Rijndael加密算法、SHA256散列校验以及CryptoStream类的应用。

386

被折叠的 条评论
为什么被折叠?



