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);
        }
    }