C# 4.0 填充无效,无法从解密值中删除

C# 4.0 填充无效,无法从解密值中删除,c#-4.0,encryption,cryptography,C# 4.0,Encryption,Cryptography,你好,我想加密和解密文本。我的加密代码工作正常,与我想要的值匹配。但当我想要解密时,这是一个错误填充无效,无法删除。在下面的代码中,我首先给出加密和解密这两个代码。我还必须修复这个错误,但不能修复它 string getHashKey1 = EncryptText("10002:1486703720424", "hpIw4SgN)TxJdoQj=GKo)p83$uHePgoF"); 结果=1ltQFLRGNif73uCNzi0YEvBqLKiRgx6fWsk5e/GcTQc= string

你好,我想加密和解密文本。我的加密代码工作正常,与我想要的值匹配。但当我想要解密时,这是一个错误
填充无效,无法删除
。在下面的代码中,我首先给出加密和解密这两个代码。我还必须修复这个错误,但不能修复它

string getHashKey1 = EncryptText("10002:1486703720424", "hpIw4SgN)TxJdoQj=GKo)p83$uHePgoF");
结果=
1ltQFLRGNif73uCNzi0YEvBqLKiRgx6fWsk5e/GcTQc=

 string reverseKey = DecryptText('1ltQFLRGNif73uCNzi0YEvBqLKiRgx6fWsk5e/GcTQc=', "hpIw4SgN)TxJdoQj=GKo)p83$uHePgoF");
当我加入AES时,解密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;
    }
上面的代码对于加密来说运行良好。 下面的代码出现错误
填充无效,无法删除

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

解密时正在对密码进行哈希运算

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

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

解密时您正在对密码进行哈希运算

passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
但不是在加密时。这意味着您正在使用不同的密码

您有两个问题:

1) (佩德罗夫已经指出):在加密中使用
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)链接。建议在ECB上使用密码块链接(CBC)

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

您有两个问题:

1) (佩德罗夫已经指出):在加密中使用
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)链接。建议在ECB上使用密码块链接(CBC)


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

解密
passwordBytes=SHA256.Create().ComputeHash(passwordBytes)时,您正在对密码进行哈希运算,但不是在encrypt@pedrofb我需要做什么当我Decrypt@pedrofb谢谢,我删除了那条线,现在它工作了。谢天谢地,仅仅使用散列函数是不够的,仅仅添加一个salt对提高安全性几乎没有什么作用。取而代之的是,在HMAC上随机添加盐,持续约100毫秒,并将盐与散列一起保存。使用诸如
PBKDF2
password\u hash
Bcrypt
等函数和类似函数。关键是让攻击者花费大量时间用暴力寻找密码。永远不要使用。它是确定性的,因此在语义上不安全。您至少应该使用随机模式,如或。最好是对密文进行身份验证,这样就不可能进行类似的攻击。这可以通过身份验证模式(如GCM或EAX)或方案来完成。解密
passwordBytes=SHA256.Create().ComputeHash(passwordBytes)时,您正在散列密码,但不是在encrypt@pedrofb我需要做什么当我Decrypt@pedrofb谢谢,我删除了那条线,现在它工作了。谢天谢地,仅仅使用散列函数是不够的,仅仅添加一个salt对提高安全性几乎没有什么作用。取而代之的是,在HMAC上随机添加盐,持续约100毫秒,并将盐与散列一起保存。使用诸如
PBKDF2
password\u hash
Bcrypt
等函数和类似函数。关键是让攻击者花费大量时间用暴力寻找密码。永远不要使用。它是确定性的,因此在语义上不安全。您至少应该使用随机模式,如或。最好是对密文进行身份验证,这样就不可能进行类似的攻击。这可以通过认证模式(如GCM或EAX)完成,也可以通过方案完成。谢谢投票给您的答案。我已经用了3个小时来找出错误,谢谢投票给你的答案。我已经用了3个小时来找出错误