解密过程中“填充无效,无法删除”

时间:2016-11-03 21:54:50

标签: c# encryption

首先,我意识到有很多其他帖子都有这个问题的答案,我已经阅读并尝试了所有这些。我似乎仍然无法解决这个问题所以我正在寻找一些比我更了解密码的人的帮助。

其次,我要分享的代码是遗留的,因为我不是加密专家,所以一切都意味着它仍然不是100%清楚。可能是这些代码中的部分或全部是完全垃圾,应该废弃;但是,有很多其他系统已经在使用它并存储了经过此代码的加密值。此时更改密码算法等内容并不是一个选项。话虽如此,私有方法是遗留代码,测试值(即加密密钥)是所有不能改变的东西。这两种公共静态方法是新的,可能会导致问题,但我似乎无法弄明白。

开启代码......

class Program
{
    public static string Encrypt(string key, string toEncrypt)
    {
        var keyArray = Convert.FromBase64String(key);
        var info = Encoding.ASCII.GetBytes(toEncrypt);

        var encrypted = Encrypt(keyArray, info);

        return Encoding.ASCII.GetString(encrypted);
    }

    public static string Decrypt(string key, string cipherString)
    {
        var keyArray = Convert.FromBase64String(key);
        var cipherText = Encoding.ASCII.GetBytes(cipherString);

        var decrypted = Decrypt(keyArray, cipherText);

        return Encoding.ASCII.GetString(decrypted);
    }

    private static byte[] Encrypt(byte[] key, byte[] info)
    {
        using (var cipher = Aes.Create())
        {
            cipher.Key = key;
            cipher.Mode = CipherMode.CBC;
            cipher.Padding = PaddingMode.ISO10126;

            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, cipher.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(info, 0, info.Length);
                }

                var ciphertext = ms.ToArray();

                var message = new byte[cipher.IV.Length + ciphertext.Length];
                cipher.IV.CopyTo(message, 0);
                ciphertext.CopyTo(message, cipher.IV.Length);
                return message;
            }
        }
    }

    private static byte[] Decrypt(byte[] key, byte[] ciphertext)
    {
        using (var cipher = Aes.Create())
        {
            cipher.Key = key;
            cipher.Mode = CipherMode.CBC;
            cipher.Padding = PaddingMode.ISO10126;

            var ivSize = cipher.IV.Length;
            var iv = new byte[ivSize];
            Array.Copy(ciphertext, iv, ivSize);
            cipher.IV = iv;

            var data = new byte[ciphertext.Length - ivSize];
            Array.Copy(ciphertext, ivSize, data, 0, data.Length);

            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, cipher.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(data, 0, data.Length);
                }

                return ms.ToArray();
            }
        }
    }

    static void Main(string[] args)
    {
        var newEncryptionKey = Guid.NewGuid().ToString().Replace("-", string.Empty);

        var encryptedValue = Encrypt(newEncryptionKey, "test");

        Console.WriteLine($"New encrypted value: {encryptedValue}");

        var decryptedValue = Decrypt(newEncryptionKey, encryptedValue);

        Console.WriteLine($"New decrypted value: {decryptedValue}");
    }
}

就是这样。基本上,我试图使用测试字符串“test”并使用GUID作为密钥加密它。同样,我没有选择此密钥,并且已经使用GUID作为密钥的加密值,所以如果可能的话我无法改变它。加密工作正常,但是当我去解密时,我得到了这个问题标题中提到的异常。

任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:1)

您不能只将byte[]密文转换为ASCII。它没有这样的工作。字符编码是可怕的野兽,如果你不理解它们,不应混淆。我不认为有一个真人活着;)

应该做的是将结果作为base64返回,它仍然是ASCII字符的集合,但它们可以安全地作为字符串移动,并且不会导致失去任何角色。

请参阅以下修改后的代码:

public static string Encrypt(string key, string toEncrypt)
{
    var keyArray = Convert.FromBase64String(key);
    var info = Encoding.ASCII.GetBytes(toEncrypt);

    var encrypted = Encrypt(keyArray, info);

    return Convert.ToBase64String(encrypted);
}

public static string Decrypt(string key, string cipherString)
{
    var keyArray = Convert.FromBase64String(key);
    var cipherText = Convert.FromBase64String(cipherString);

    var decrypted = Decrypt(keyArray, cipherText);

    return Encoding.ASCII.GetString(decrypted);
}