【问题标题】:Decrypting byte array with SymmetricAlgorithm and CryptoStream使用 SymmetricAlgorithm 和 CryptoStream 解密字节数组
【发布时间】:2017-03-16 12:25:33
【问题描述】:

我的加解密方法:

private static SymmetricAlgorithm GetAlgorithm(string password)
{
    using (Rijndael algorithm = Rijndael.Create())
    {
        using (Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(password, new byte[]
        {
            0x53, 0x6f, 0x64, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x68, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x65
        }))
        {
            algorithm.Padding = PaddingMode.ISO10126;
            algorithm.Key = rdb.GetBytes(32);
            algorithm.IV = rdb.GetBytes(16);
        }
        return algorithm;
    }
}

public static byte[] EncryptBytes(byte[] clearBytes, string password)
{
    ICryptoTransform encryptor;
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password))
        encryptor = algorithm.CreateEncryptor();
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
    {
        cs.Write(clearBytes, 0, clearBytes.Length);
        cs.FlushFinalBlock();
        return ms.ToArray();
    }
}

public static byte[] DecryptBytes(byte[] cipherBytes, string password)
{
    ICryptoTransform decryptor;
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password))
        decryptor = algorithm.CreateDecryptor();
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
    {
        cs.Write(cipherBytes, 0, cipherBytes.Length); //here is the exception thrown
        cs.FlushFinalBlock();
        return ms.ToArray();
    }
}

我如何调用方法:

byte[] prev = File.ReadAllBytes(path + sourcefile);
byte[] enc = Encryption.EncryptBytes(prev, password);
byte[] dec = Encryption.DecryptBytes(enc, password);

File.WriteAllBytes(path + targetfile, dec);

当我尝试解密字节数组时,出现以下异常:

System.Security.Cryptography.CryptographicException
Additional information: padding is invalid and cannot be removed

我已经阅读了一些可能的解决方案,但没有一个能解决我的问题。 当我加密和解密时,密钥和 IV(InitialisationVector)是相同的,所以这绝对不是原因。

【问题讨论】:

  • GetAlgorithm 是错误的:您返回的是 Disposed algorithm
  • 但是我什么时候需要处理它呢?
  • 你是DisposingGetAlgorithm()的调用方法中的算法

标签: c# encryption encryption-symmetric rijndael


【解决方案1】:

更正的方法:

错误:您在 GetAlgorithm() 中处理了 Rijndael algorithm。这是错误的:必须处理 algorithm 的是 GetAlgorithm() 的调用者(正如你所做的那样)

private static SymmetricAlgorithm GetAlgorithm(string password)
{
    Rijndael algorithm = Rijndael.Create();

    using (Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(password, new byte[]
    {
        0x53, 0x6f, 0x64, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x68, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x65
    }))
    {
        algorithm.Padding = PaddingMode.ISO10126;
        algorithm.Key = rdb.GetBytes(32);
        algorithm.IV = rdb.GetBytes(16);
    }

    return algorithm;
}

这里的小警告:你没有处理ICryptoTransform

public static byte[] EncryptBytes(byte[] clearBytes, string password)
{
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password))
    using (ICryptoTransform encryptor = algorithm.CreateEncryptor())
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
    {
        cs.Write(clearBytes, 0, clearBytes.Length);
        cs.FlushFinalBlock();
        return ms.ToArray();
    }
}

public static byte[] DecryptBytes(byte[] cipherBytes, string password)
{
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password))
    using (ICryptoTransform decryptor = algorithm.CreateDecryptor())
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
    {
        cs.Write(cipherBytes, 0, cipherBytes.Length); //here is the exception thrown
        cs.FlushFinalBlock();
        return ms.ToArray();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多