2012-05-14 50 views
0

我正在使用“AesManaged”加密和解密Web应用程序中受保护的数据。在我的场景中,我在用户登录时创建基于“Email + CurrentDate”的令牌,并以加密格式将其发回给用户(使用AESManaged类加密),并且当用户调用下一个服务器端方法时,例如“显示报告“,用户/客户端应用程序也将发送带有请求的加密标记。在服务器端,我解密令牌,并在根据解密的令牌执行条件逻辑之后,决定给定用户是否有权访问此方法(一种授权检查)。如何避免AESManaged(C#)“要解密的数据的长度无效。”

对于基本流程,用户提供正确的加密字符串(他从服务器获取的加密字符串或长度相同但用户替换加密字符串中的字符)表现良好(如预期的那样)。

但是,问题出现时,当用户得到(例如)54字符的字符串,但只发送7个字符的服务器。然后发生以下异常。

即使用户提供无效数据,我也想避免这种异常。所以,基本上应该总是解密字符串,如果它是无效的令牌,那么我可以限制对资源的访问。我怎么能做到这一点?您的答复将不胜感激。

异常详细信息:

具体代码块,其中的例外发生。

// Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 
        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
        { 
         using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 
         { 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 

例外情况:“要解密的数据的长度无效。”

异常详细信息:

目标站点:{字节[] TransformFinalBlock(字节[],的Int32,Int32)将}

声明类型:{名称= “RijndaelManagedTransform” 全名=“System.Security .Cryptography.RijndaelManagedTransform“}

名称: TransformFinalBlock

注:我为加密和解密方法提供了相同的密钥和iv。

代码:

public string EncryptAuthenticationTokenAes(string plainText, byte[] Key, byte[] IV) 
     { 


      byte[] encrypted; 
      // Create an AesManaged object 
      // with the specified key and IV. 
      using (AesManaged aesAlg = new AesManaged()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 


       // Create a decrytor to perform the stream transform. 
       ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 

       // Create the streams used for encryption. 
       using (MemoryStream msEncrypt = new MemoryStream()) 
       { 
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
        { 
         using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
         { 

          //Write all data to the stream. 
          swEncrypt.Write(plainText); 
         } 
         encrypted = msEncrypt.ToArray(); 
        } 
       } 
      } 
      // Return the encrypted bytes from the memory stream. 
      return Convert.ToBase64String(encrypted); 

     } 

     public string DecryptPasswordAes(string encryptedString, byte[] Key, byte[] IV) 
     { 
      // becuase it is base64, if mod4>0 then it is consider as invalid token 
      int mod4 = encryptedString.Length % 4; 
      if (mod4 > 0) 
      { 
       return string.Empty; 
      } 
      byte[] cipherText = Convert.FromBase64String(encryptedString); 
      // Declare the string used to hold 
      // the decrypted text. 
      string plaintext = null; 

      // Create an AesManaged object 
      // with the specified key and IV. 
      using (AesManaged aesAlg = new AesManaged()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 

       // Create a decrytor to perform the stream transform. 
       ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); 

       // Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 
        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
        { 
         using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 
         { 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 

      } 

      return plaintext; 
     } 

回答

0

尝试加密字符串这

  // Create the streams used for decryption. 
      using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
      { 
       using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
       { 
        using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 
        { 
         if (encryptedString.Length != aesAlg.BlockSize) 
         { 
          // Handle invalid token here. 
         } 
         plaintext = srDecrypt.ReadToEnd(); 
        } 
       } 
      } 
1

它告诉你,有没有办法为它取的7个字符,并对其进行任何有意义的变革 - 它无法执行使用它们任何一种解密。

在尝试解密之前执行长度检查,或者捕获异常;无论哪种情况,只要沿着“收到无效令牌”的路线走下去。

0

保存长度,然后检查是否长度是相同的。如果是,则继续调用解密方法。

相关问题