C# 要解密的数据的对称算法长度无效

C# 要解密的数据的对称算法长度无效,c#,encryption,C#,Encryption,我得到要解密的数据长度无效异常,无任何实际原因使用此代码 /// <summary> /// Extension generic method that encrypts a byte[] using the specified SymmetricAlgorithm. /// </summary> /// <typeparam name="T">The SymmetricAlgorithm to be used.</typeparam> /// &

我得到要解密的
数据长度无效
异常,无任何实际原因使用此代码

/// <summary>
/// Extension generic method that encrypts a byte[] using the specified SymmetricAlgorithm.
/// </summary>
/// <typeparam name="T">The SymmetricAlgorithm to be used.</typeparam>
/// <param name="value">The value to encrypt.</param>
/// <param name="password">The password for encryption.</param>
/// <param name="salt">The salt for encryption.</param>
/// <returns></returns>
public static byte[] EncryptBytes<T>(this byte[] value, byte[] password, byte[] salt)
    where T : SymmetricAlgorithm, new()
{
    DeriveBytes rgb = new Rfc2898DeriveBytes(Encoding.Unicode.GetString(password), salt);
    SymmetricAlgorithm algorithm = new T();
    byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
    byte[] rgbIv = rgb.GetBytes(algorithm.BlockSize >> 3);
    ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIv);

    using (var buffer = new MemoryStream())
    {
        using (var stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
        {
            using (var writer = new StreamWriter(stream, Encoding.Unicode))
            {
                writer.Write(value);
            }
        }
        return buffer.ToArray();
    }
}

/// <summary>
/// Extension generic method that decrypts a byte[] using the specified SymmetricAlgorithm.
/// </summary>
/// <typeparam name="T">The SymmetricAlgorithm to be used.</typeparam>
/// <param name="value">The value to decrypt.</param>
/// <param name="password">The password for decryption.</param>
/// <param name="salt">The salt for decryption.</param>
/// <returns></returns>
public static byte[] DecryptBytes<T>(this byte[] value, byte[] password, byte[] salt)
    where T : SymmetricAlgorithm, new()
{
    DeriveBytes rgb = new Rfc2898DeriveBytes(Encoding.Unicode.GetString(password), salt);
    SymmetricAlgorithm algorithm = new T();
    byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
    byte[] rgbIv = rgb.GetBytes(algorithm.BlockSize >> 3);
    ICryptoTransform transform = algorithm.CreateDecryptor(rgbKey, rgbIv);

    using (var buffer = new MemoryStream(value)) {
        using (var stream = new CryptoStream(buffer, transform, CryptoStreamMode.Read)) {
            stream.Read(value, 0, value.Length);
        }
        return buffer.ToArray();
    }
}

/// <summary>
/// Extension generic method that encrypts a string using the specified SymmetricAlgorithm.
/// </summary>
/// <typeparam name="T">The SymmetricAlgorithm to be used.</typeparam>
/// <param name="value">The value to encrypt.</param>
/// <param name="password">The password for encryption.</param>
/// <param name="salt">The salt for encryption.</param>
/// <returns></returns>
public static string EncryptString<T>(this string value, byte[] password, byte[] salt)
    where T : SymmetricAlgorithm, new()
{
    return Convert.ToBase64String(EncryptBytes<T>(Encoding.UTF8.GetBytes(value), password, salt));
}

/// <summary>
/// Extension generic method that decrypts a string using the specified SymmetricAlgorithm.
/// </summary>
/// <typeparam name="T">The SymmetricAlgorithm to be used.</typeparam>
/// <param name="value">The value to decrypt.</param>
/// <param name="password">The password for decryption.</param>
/// <param name="salt">The salt for decryption.</param>
/// <returns></returns>
public static string DecryptString<T>(this string value, byte[] password, byte[] salt)
    where T : SymmetricAlgorithm, new()
{
    return Encoding.UTF8.GetString(DecryptBytes<T>(Convert.FromBase64String(value), password, salt));
}
//
///使用指定的对称算法加密字节[]的扩展通用方法。
/// 
///要使用的对称算法。
///要加密的值。
///用于加密的密码。
///用于加密的盐。
/// 
公共静态字节[]加密字节(此字节[]值、字节[]密码、字节[]salt)
式中T:对称算法,new()
{
DeriveBytes rgb=新的Rfc2898DeriveBytes(Encoding.Unicode.GetString(password),salt);
对称算法=新T();
byte[]rgbKey=rgb.GetBytes(algorithm.KeySize>>3);
byte[]rgbIv=rgb.GetBytes(algorithm.BlockSize>>3);
ICryptoTransform transform=algorithm.CreateEncryptor(rgbKey,rgbIv);
使用(var buffer=new MemoryStream())
{
使用(var stream=新加密流(缓冲区、转换、加密流模式.Write))
{
使用(var writer=newstreamwriter(stream,Encoding.Unicode))
{
writer.Write(值);
}
}
返回buffer.ToArray();
}
}
/// 
///使用指定的对称算法解密字节[]的扩展通用方法。
/// 
///要使用的对称算法。
///要解密的值。
///用于解密的密码。
///用于解密的盐。
/// 
公共静态字节[]解密字节(此字节[]值、字节[]密码、字节[]salt)
式中T:对称算法,new()
{
DeriveBytes rgb=新的Rfc2898DeriveBytes(Encoding.Unicode.GetString(password),salt);
对称算法=新T();
byte[]rgbKey=rgb.GetBytes(algorithm.KeySize>>3);
byte[]rgbIv=rgb.GetBytes(algorithm.BlockSize>>3);
ICryptoTransform transform=algorithm.CreateDecryptor(rgbKey,rgbIv);
使用(var缓冲区=新内存流(值)){
使用(var stream=新加密流(缓冲区、转换、CryptoStreamMode.Read)){
读取(值,0,值,长度);
}
返回buffer.ToArray();
}
}
/// 
///使用指定的对称算法加密字符串的扩展通用方法。
/// 
///要使用的对称算法。
///要加密的值。
///用于加密的密码。
///用于加密的盐。
/// 
公共静态字符串EncryptString(此字符串值,字节[]密码,字节[]盐)
式中T:对称算法,new()
{
返回Convert.ToBase64String(EncryptBytes(Encoding.UTF8.GetBytes(value)、password、salt));
}
/// 
///使用指定的对称算法解密字符串的扩展通用方法。
/// 
///要使用的对称算法。
///要解密的值。
///用于解密的密码。
///用于解密的盐。
/// 
公共静态字符串解密字符串(此字符串值,字节[]密码,字节[]salt)
式中T:对称算法,new()
{
返回Encoding.UTF8.GetString(DecryptBytes(Convert.FromBase64String(value)、password、salt));
}

不要使用字符串处理来处理二进制数据。删除
StreamWriter

更具体地说,您正在将
字节[]
写入
文本编写器,这毫无意义。事实上,它将被写为
value.ToString()
,这不是您所期望的


或许,您也最好使用新Rfc2898DeriveBytes的重载,该重载只需要
字节[]
。同样,字符串与字节混淆。

如果纯文本是字符串,请使用
StreamReader
。如果它是二进制的,则直接从
加密流
读取。

为什么要写入
?你不应该改读吗?@owlstead那么我该怎么办?如果纯文本是字符串,我完全搞不懂从解密函数返回字节[]时使用
StreamReader
。如果是二进制的,则直接从
加密流
读取。注意,攻击者可以在您不注意的情况下修改数据。他们无法知道加密数据是什么,但仍然可以修改它。在某些情况下,它们甚至可以翻转单个位。使用经过身份验证的加密。@usr密码由服务器和客户端之间的DH密钥交换生成。这就足够了吗?那么如何直接从加密流返回解密的字节[]?也许可以使用
Stream.Copy
将内容复制到
新的MemoryStream
,然后调用
MemoryStream.ToArray
@usr,我可以发布整个代码,因为我只是一个加密初学者,有点错过了整个过程吗?我可以从一个工作代码中学到很多东西,但是我没有看到密码以字节的形式传递,对此表示歉意。但这不太可能是罪魁祸首。我也会发布我的加密函数,这样你就可以安全地编辑它,让我使用字节[]s?,很抱歉,我把一切都弄得很复杂,最好留给加密专业人士。我可以吗?。它将为其他任何想和我一样做的人提供很好的帮助。请使用
StreamReader
,就像您在加密函数中使用
StreamWriter
一样。通过我的代码,我想要实现的是拥有一个函数,该函数接受字节[],对其进行加密并返回加密数组,同样用于解密。另外,我想用一个字符串,并做同样的事情,以便有任何想法使代码更可靠(实际工作)。我真的非常感谢我的代码的工作版本,以帮助我和后面的任何人。删除读者和作者。在这种情况下,不需要对字符串执行任何操作。