Question

I'm reading a book entitled beginning asp.net security from wrox and I'm in this part where it shows a code snippet for using rijndael the problem this example is not included in the downloadable source codes. I decided to seek (professional)help here in the forums.

It would be awesome if you try and test it as well and hopefully give an example(codes) on how I could implement it.

Here is the code:

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

Sir/Ma'am your answers would be of great help. Thank you++ (it would be awesome if you could show me how to call encrypt and decrypt properly)

Was it helpful?

Solution

I have found that it is best to create a class to wrap your credentials and a separate one to do the encryption. Here is what I created... sorry it's in vb instead of 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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top