SymmetricAlgorithm要解密的数据长度无效

时间:2014-03-13 22:36:41

标签: c# encryption

我使用此代码时没有任何实际原因而得到Length of the data to decrypt is invalid异常

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

2 个答案:

答案 0 :(得分:0)

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

更具体地说,您正在向byte[]TextWriter这是没有意义的。事实上,它将被写为value.ToString(),这不是您所期望的。

或许,你也可以更好地使用仅new Rfc2898DeriveBytes的{​​{1}}重载。同样,字符串与字节混淆。

答案 1 :(得分:0)

如果明文是字符串,请使用StreamReader。如果是二进制文件,请直接从CryptoStream读取。