2017-03-08 45 views
1

您好,我想加密和解密文本。我的加密代码工作正常,并匹配我想要的值。但是当我想解密这是给错误padding is invalid and cannot be removed。在下面的代码中,我首先给出了我的加密和解密代码。此外,我必须修复这个错误Stack overflow link,StackoverlFlow 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; 
    } 
+0

当你解密passwordBytes = SHA256.Create()。ComputeHash(passwordBytes);',但不是当加密时加密 – pedrofb

+0

@pedrofb我解密时需要做什么 –

+0

@pedrofb谢谢我删除了该行现在它可以工作。谢谢 –

回答

1

你是散列密码,当你解密,

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

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

+0

感谢您的答案。我已经给了我3个小时来发现错误 –

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个字节。

相关问题