Asp.net代码不能用于实现rijndael加密,解密?

问题描述:

我正在读一本书,题为从wrox开始的asp.net安全性,我在这个部分展示了使用rijndael这个问题的代码片段,这个例子不包含在可下载的源代码中。我决定在论坛寻求(专业)帮助。Asp.net代码不能用于实现rijndael加密,解密?

如果您尝试并测试它并且希望给出一个关于如何实现它的示例(代码),那将会非常棒。

下面是代码:

public class EncryptionRijndael 
{ 
     public EncryptionRijndael() 
     { 
       // 
       // TODO: Add constructor logic here 
       // 
     } 

    public static byte[] GenerateRandomBytes(int length) 
    { 
     byte[] key = new byte[length]; 
     RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider(); 
     provider.GetBytes(key); 
     return key; 
    } 

    public void GetKeyAndIVFromPasswordAndSalt(string password, byte[] salt,SymmetricAlgorithm symmetricAlgorithm,ref byte[] key, ref byte[] iv) 
    { 
     Rfc2898DeriveBytes rfc2898DeriveBytes = 
     new Rfc2898DeriveBytes(password, salt); 
     key = 
     rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize/8); 
     iv = 
     rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize/8); 
    } 

    public static byte[] Encrypt(byte[] clearText, byte[] key, byte[] iv) 
    { 
     // Create an instance of our encyrption algorithm. 
     RijndaelManaged rijndael = new RijndaelManaged(); 
     // Create an encryptor using our key and IV 
     ICryptoTransform transform = rijndael.CreateEncryptor(key, iv); 
     // Create the streams for input and output 
     MemoryStream outputStream = new MemoryStream(); 
     CryptoStream inputStream = new CryptoStream(
     outputStream, 
     transform, 
     CryptoStreamMode.Write); 
     // Feed our data into the crypto stream. 
     inputStream.Write(clearText, 0, clearText.Length); 
     // Flush the crypto stream. 
     inputStream.FlushFinalBlock(); 
     // And finally return our encrypted data. 
     return outputStream.ToArray(); 
    } 

    static byte[] Decrypt(byte[] cipherText, byte[] key, byte[] iv) 
    { 
     // Create an instance of our encyrption algorithm. 
     RijndaelManaged rijndael = new RijndaelManaged(); 
     // Create an decryptor using our key and IV ; 
     ICryptoTransform transform = rijndael.CreateDecryptor(key, iv); 
     // Create the streams for input and output 
     MemoryStream outputStream = new MemoryStream(); 
     CryptoStream inputStream = new CryptoStream(outputStream,transform,CryptoStreamMode.Write); 
     // Feed our data into the crypto stream. 
     inputStream.Write(cipherText, 0, cipher.Length); 
     // Flush the crypto stream. 
     inputStream.FlushFinalBlock(); 
     // And finally return our decrypted data. 
     return outputStream.ToArray(); 
    } 
} 

先生/女士你的答案会是很大的帮助。谢谢++ (如果你能告诉我如何正确调用加密和解密,这将是非常棒的)

+0

使用固定的IV失败了CBC的目的。您需要为每封邮件使用不同的IV。 – SLaks

我发现最好是创建一个类来包装你的凭证,并单独做一个加密。这是我创建的...对不起,这是在vb而不是c#:

Public Class SymmetricEncryptionCredentials 
     Private _keyIterations As Integer 

     Public ReadOnly Property ivString As String 
      Get 
       Return Convert.ToBase64String(Me.iv) 
      End Get 
     End Property 
     Public ReadOnly Property saltString() As String 
      Get 
       Return Convert.ToBase64String(Me.salt) 
      End Get 
     End Property 
     Public ReadOnly Property keyIterations As Integer 
      Get 
       Return _keyIterations 
      End Get 
     End Property 

     Private Property keyPassword() As String 
     Private Property salt() As Byte() 
     Private ReadOnly Property key() As Security.Cryptography.Rfc2898DeriveBytes 
      Get 
       Return New Security.Cryptography.Rfc2898DeriveBytes(keyPassword, salt, keyIterations) 
      End Get 
     End Property 
     Private Property iv() As Byte() 

     ''' <summary> 
     ''' Creates a set of encryption credentials based on the 
     ''' provided key, ivPassword, and salt string. 
     ''' </summary> 
     ''' <param name="keyPassword">The Secret key used for encryption</param> 
     ''' <param name="salt">The salt string (not secret) from which the salt 
     ''' bytes are derived.</param> 
     ''' <remarks></remarks> 
     Public Sub New(ByVal keyPassword As String, ByVal salt As String, ByVal iv As String, ByVal keyIterations As Integer) 

      Me.keyPassword = keyPassword 
      Me.iv = Convert.FromBase64String(iv) 
      Me.salt = Convert.FromBase64String(salt) 
      _keyIterations = keyIterations 
     End Sub 
     ''' <summary> 
     ''' Creates a new set of encryption credentials based on the 
     ''' provided key, while making a ivPassword and salt. 
     ''' </summary> 
     ''' <param name="keyPassword">The Secret key used for encryption</param> 
     ''' <remarks>Creates a new set of encryption credentials based on the 
     ''' provided key password, while making a ivPassword and salt.</remarks> 
     Public Sub New(ByVal keyPassword As String, ByVal keyIterations As Integer) 
      Me.keyPassword = keyPassword 
      Me.iv = Passwords.GetRandomPassword(16, 16) 
      Me.salt = Passwords.GetRandomPassword() 
      _keyIterations = keyIterations 
     End Sub 
     ''' <summary> 
     ''' Creates a new set of encryption credentials based on the 
     ''' provided key, while making a ivPassword and salt. Uses 
     ''' default PBKDF iteration count. 
     ''' </summary> 
     ''' <param name="keyPassword">The Secret key used for encryption</param> 
     ''' <remarks>Creates a new set of encryption credentials based on the 
     ''' provided key password, while making a ivPassword and salt.</remarks> 
     Public Sub New(ByVal keyPassword As String) 
      Me.New(keyPassword, AppSettings("defaultKeyPBKDFIterations")) 
     End Sub 
     ''' <summary> 
     ''' Gets an AES Encryptor with key derived from RFC2898. 
     ''' </summary> 
     ''' <returns></returns> 
     ''' <remarks></remarks> 
     Public Function GetAESEncryptor() As Security.Cryptography.ICryptoTransform 

      Dim aes As New Security.Cryptography.AesManaged 

      aes.KeySize = 256 
      aes.Key = Me.key.GetBytes(aes.KeySize/8) 
      aes.IV = Me.iv 
      Return aes.CreateEncryptor() 

     End Function 
     Public Function GetAESDecryptor() As Security.Cryptography.ICryptoTransform 

      Dim aes As New Security.Cryptography.AesManaged 
      aes.KeySize = 256 
      aes.Key = Me.key.GetBytes(aes.KeySize/8) 
      aes.IV = Me.iv 
      Return aes.CreateDecryptor 

     End Function 

    End Class 

Public Class SymmetricEncryption 
     Public Shared Function Encrypt(ByVal unencryptedValue As String, creds As SymmetricEncryptionCredentials) As String 
      Dim inBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(unencryptedValue) 
      Dim outBytes() As Byte 

      Using outStream As New IO.MemoryStream() 
       Using encryptStream As New System.Security.Cryptography.CryptoStream(outStream, creds.GetAESEncryptor, Security.Cryptography.CryptoStreamMode.Write) 
        encryptStream.Write(inBytes, 0, inBytes.Length) 
        encryptStream.FlushFinalBlock() 
        outBytes = outStream.ToArray 
        encryptStream.Close() 

       End Using 
       outStream.Close() 
      End Using 
      Dim outString As String = Convert.ToBase64String(outBytes) 

      Return outString 
     End Function 
     Public Shared Function Decrypt(ByVal encryptedValue As String, creds As SymmetricEncryptionCredentials) As String 

      Dim inBytes() As Byte = Convert.FromBase64String(encryptedValue) 
      Dim outString As String 
      Using outStream As New IO.MemoryStream 
       Using decryptionStream As New System.Security.Cryptography.CryptoStream(outStream, creds.GetAESDecryptor, Security.Cryptography.CryptoStreamMode.Write) 
        decryptionStream.Write(inBytes, 0, inBytes.Length) 
        decryptionStream.FlushFinalBlock() 

        Dim outBytes() As Byte = outStream.ToArray 

        outString = System.Text.Encoding.UTF8.GetString(outBytes) 
        decryptionStream.Close() 
       End Using 
       outStream.Close() 
      End Using 
      Return outString 
     End Function 
    End Class 

    Public Class Passwords 

     Public Shared Function GetRandomPassword(minLength As Integer, maxlength As Integer) As Byte() 
      ' *** 1. Get how long the password will be 
      Dim rand As New Random 
      Dim passLength As Integer = rand.Next(minLength, maxlength) 

      ' *** 2. Create an array of Bytes to hold the 
      '   random numbers used to make the string's chars 
      Dim passBytes(passLength - 1) As Byte 

      ' *** 3. Fill the array with random bytes. 
      Dim rng As New Security.Cryptography.RNGCryptoServiceProvider 
      rng.GetBytes(passBytes) 

      Return passBytes 

     End Function 
     Public Shared Function GetRandomPassword() As Byte() 

      Return GetRandomPassword(12, 32) 

     End Function 
End Class