C# 单向加密和解密意外动作
我有两个函数可以对给定文件进行加密和解密:C# 单向加密和解密意外动作,c#,encryption,C#,Encryption,我有两个函数可以对给定文件进行加密和解密: publicstaticvoidencrypt(字符串名,字符串skey) { 使用(var sourceStream=File.OpenRead(name)) 使用(var destinationStream=File.Create(name+“.sav”)) 使用(var provider=new AESCryptServiceProvider()) 使用(var cryptoTransform=provider.CreateEncryptor()
publicstaticvoidencrypt(字符串名,字符串skey)
{
使用(var sourceStream=File.OpenRead(name))
使用(var destinationStream=File.Create(name+“.sav”))
使用(var provider=new AESCryptServiceProvider())
使用(var cryptoTransform=provider.CreateEncryptor())
使用(var cryptoStream=new cryptoStream(destinationStream、cryptoTransform、CryptoStreamMode.Write))
{
provider.Padding=PaddingMode.None;
列表键=新列表();
AddRange(ascienceoding.ASCII.GetBytes(skey));
while(key.Count<32)
{
键。添加(0);
}
provider.Key=Key.ToArray();
destinationStream.Write(provider.IV,0,provider.IV.Length);
CopyTo(加密流);
}
}
公共静态无效解密(字符串名称、字符串skey)
{
//解密源文件并将其写入目标文件。
使用(var sourceStream=File.OpenRead(name+“.sav”))
使用(var destinationStream=File.Create(name))
使用(var provider=new AESCryptServiceProvider())
{
provider.Padding=PaddingMode.None;
列表键=新列表();
AddRange(ascienceoding.ASCII.GetBytes(skey));
while(key.Count<32)
{
键。添加(0);
}
var IV=新字节[provider.IV.Length];
sourceStream.Read(IV,0,IV.Length);
使用(var cryptoTransform=provider.CreateDecryptor(key.ToArray(),IV))
使用(var cryptoStream=new cryptoStream(sourceStream、cryptoTransform、CryptoStreamMode.Read))
{
cryptoStream.CopyTo(destinationStream);
}
}
}
使用文本文件(d):
D
福
以下节目:
static void Main(string[] args)
{
string pass = "foo";
Encrypt("d", pass);
Decrypt("d", pass);
}
文本文件(d)中的结果:
似乎解密消息会导致意外的结果,但是除了随机噪声之外,我在“*.sav”文件中没有预期的结果。检查监视列表
提供程序。key
是一个数组,它读取1021111110。。。0
在加密
和解密
两种方法中。好的,您的问题是您正在创建加密程序,但从未将其设置为IV
更改加密
方法,如下所示:
public static void Encrypt(string name, string skey)
{
// First, process key
List<byte> key = new List<byte>();
key.AddRange(ASCIIEncoding.ASCII.GetBytes(skey));
while (key.Count < 32)
{
key.Add(0);
}
using (var sourceStream = File.OpenRead(name))
using (var destinationStream = File.Create(name + ".sav"))
using (var provider = new AesCryptoServiceProvider())
using (var cryptoTransform = provider.CreateEncryptor(key.ToArray(), provider.IV)) // when creating Encryptor pass the key and the IV of the provider.
using (var cryptoStream = new CryptoStream(destinationStream, cryptoTransform, CryptoStreamMode.Write))
{
provider.Padding = PaddingMode.None;
provider.Key = key.ToArray();
destinationStream.Write(provider.IV, 0, provider.IV.Length);
sourceStream.CopyTo(cryptoStream);
}
}
publicstaticvoidencrypt(字符串名,字符串skey)
{
//首先,进程密钥
列表键=新列表();
AddRange(ascienceoding.ASCII.GetBytes(skey));
while(key.Count<32)
{
键。添加(0);
}
使用(var sourceStream=File.OpenRead(name))
使用(var destinationStream=File.Create(name+“.sav”))
使用(var provider=new AESCryptServiceProvider())
使用(var cryptoTransform=provider.CreateEncryptor(key.ToArray(),provider.IV))//在创建加密程序时传递提供程序的密钥和IV。
使用(var cryptoStream=new cryptoStream(destinationStream、cryptoTransform、CryptoStreamMode.Write))
{
provider.Padding=PaddingMode.None;
provider.Key=Key.ToArray();
destinationStream.Write(provider.IV,0,provider.IV.Length);
CopyTo(加密流);
}
}
OK,这是使用CBC模式加密(OK-ish用于就地加密),在密文前加上随机IV前缀(好),不加填充(坏)。然而,错误显然与填充无关。首先创建提供者,然后创建流,然后启动提供者的顺序有点问题。这听起来并不完全正确。否则,我看不到任何直接错误。@MaartenBodewes这是为了在游戏中加密数据,所以完美的加密并不必要,只是足以阻止任何人在合理的时间内找到内容。我应该在使用(provider…之前使用(cryptoTransform…移动和使用(cryptoStream…
),然后在括号中初始化这三个吗?我目前没有可用的C#IDE,这当然是我会尝试的。嗯,这似乎是正确的,但我还是有点惊讶,因为destinationStream.Write(provider.IV,0,provider.IV.Length);
在原始代码中应该写入正确的IV。显然它没有;可能是在加密之前生成的(?)。哦,好吧,最好是显式设置,我不喜欢那种默认设置。@MaartenBodewes IV是在提供程序上设置的,但不是在加密程序上设置的。如果您是第一次这样做,这有点令人困惑,但本质上提供程序“提供”了IV,但它是供您使用的。
public static void Encrypt(string name, string skey)
{
// First, process key
List<byte> key = new List<byte>();
key.AddRange(ASCIIEncoding.ASCII.GetBytes(skey));
while (key.Count < 32)
{
key.Add(0);
}
using (var sourceStream = File.OpenRead(name))
using (var destinationStream = File.Create(name + ".sav"))
using (var provider = new AesCryptoServiceProvider())
using (var cryptoTransform = provider.CreateEncryptor(key.ToArray(), provider.IV)) // when creating Encryptor pass the key and the IV of the provider.
using (var cryptoStream = new CryptoStream(destinationStream, cryptoTransform, CryptoStreamMode.Write))
{
provider.Padding = PaddingMode.None;
provider.Key = key.ToArray();
destinationStream.Write(provider.IV, 0, provider.IV.Length);
sourceStream.CopyTo(cryptoStream);
}
}