填充无效,无法删除解密值

时间:2017-03-08 08:48:53

标签: c#-4.0 encryption cryptography

您好我想要加密和解密文本。我的加密代码工作正常,匹配我想要的值。但是当我想要Decrypt时,这会给出错误padding is invalid and cannot be removed。在下面的代码中,我首先给出了我的加密和解密代码。此外,我必须修复此错误Stack overflow linkStackoverlFlow Link 2,但无法解决此问题。

string getHashKey1 = EncryptText("10002:1486703720424", "hpIw4SgN)TxJdoQj=GKo)p83$uHePgoF");

结果= 1ltQFLRGNif73uCNzi0YEvBqLKiRgx6fWsk5e/GcTQc=

 string reverseKey = DecryptText('1ltQFLRGNif73uCNzi0YEvBqLKiRgx6fWsk5e/GcTQc=', "hpIw4SgN)TxJdoQj=GKo)p83$uHePgoF");

当我添加AES_Decrypt aes.Padding = PaddingMode.Zeros;我得到低于结果。     结果: - ����y�7�t���Ij���,���� Z��$�

public string EncryptText(string input, string password)
    {
        string result = "";
        try
        {
            // Get the bytes of the string
            byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

            byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

             result = Convert.ToBase64String(bytesEncrypted);
            return result;
        }
        catch (Exception ex)
        {

        }

        return result;
    }

public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
    {
        byte[] encryptedBytes = null;
        try
        {     
            using (MemoryStream ms = new MemoryStream())
            {
                using (Aes aes = Aes.Create())
                {
                    aes.Key = passwordBytes;
                    aes.Mode = CipherMode.ECB;

                    // "zero" IV
                    aes.IV = new byte[16];

                    using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                        cs.Close();
                    }
                    encryptedBytes = ms.ToArray();
                }
            }
        }
        catch (Exception ex)
        {

        }            
        return encryptedBytes;
    }

以上代码适用于加密。  以下代码提供错误 padding is invalid and cannot be removed

 public string DecryptText(string input, string password)
    {
        // Get the bytes of the string
        byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
        passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

        byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);

        string result = Encoding.UTF8.GetString(bytesDecrypted);

        return result;
    }


 public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
    {
        byte[] decryptedBytes = null;

        using (MemoryStream ms = new MemoryStream())
        {
            using (Aes aes = Aes.Create())
            {
                aes.Key = passwordBytes;
                aes.Mode = CipherMode.ECB;
                aes.IV = new byte[16];                  

                using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                    cs.Close();  // here i am getting error 
                }
                decryptedBytes = ms.ToArray();
            }
        }

        return decryptedBytes;
    }

2 个答案:

答案 0 :(得分:3)

你有两个问题:

1)(已经由pedrofb指出):您在加密时使用UTF8.GetBytes,但在解密中使用SHA256(UTF8.GetBytes())

您不应该使用这些方法中的任何一种,而应使用适当的基于密码的密钥派生函数,例如PBKDF2。在.NET中,PBKDF2可通过Rfc2898DeriveBytes类获得。

byte[] salt = 8 or more bytes that you always pass in as the same.
// (salt could be fixed for your application,
// but if you have users it should be unique per user and stored along with the output value)
int iterations = 100000;
// Or bigger. If you were making a user management system you
// should write this number down, too, so you can increase it over time;
// it should be whatever number makes it take 100ms or more on the fastest relevant computer)
Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations);
passwordBytes = pbkdf2.GetBytes(16); // 16 = AES128, 24 = AES192, 32 = AES256.

2)您在加密时使用Base64编码,但在解密时使用UTF8.GetBytes。

奖金问题:

3)您正在使用电子密码本(ECB)链接。建议使用密码块链(CBC),而不是ECB。

要正确使用CBC,请在加密中生成随机初始化向量(IV)(在创建新的Aes对象时自动完成,或者如果您在加密时调用GenerateIV()重用对象)。然后,您可以将IV(对于AES将始终为16个字节)添加到密文。在解密中,您可以a)中断前16个字节并将其指定为IV(然后解密其余数据)或b)解密整个blob并忽略解密输出的前16个字节。

答案 1 :(得分:1)

解密时正在哈希密码,

passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

但不是加密时。这意味着您使用的是不同的密码