# VBForums CodeBank > CodeBank - Visual Basic .NET >  VB.NET - Symmetric Encryption/Decryption (Not using files)

## SnOrfus

Half of the code online that I could find was useless. All of the msdn examples read in from a file, and then output it all to a file... and all of the 'tutorials' that I've found online have serious issues that are always left unanswered. It should also be noted that this code was made in Beta 2.0 of the .NET framework, but it works in 1.1.

First of all, this is the interface that the encryption classes will follow. This allows us to easily create an abstract factory where we can add new encryption algorithms, and create them without changing much of the existing code.


```
Public Interface ICrypto
    Function BlockSize() As Integer
    Function KeySize() As Integer

    Function Encrypt(ByVal data As String) As String
    Function Decrypt(ByVal data As String) As String
End Interface
```

The abstract factory that will create whatever cryptographic object we have available. Just pass in the name of the encryption that you want to use, and it gives you back the object. (More on this in a second)


```
Public Class CryptoFactory
    Public Function MakeCryptographer(ByVal type As String) As ICrypto
        Select Case type.ToLower
            Case "des"
                Return New DES()
            Case "tripledes"
                Return New TripleDES()
            Case "rijndael"
                Return New Rijndael()
            Case Else
                Return New TripleDES()
        End Select
    End Function
End Class
```

Here are the goods. This will perform the encryption and decryption. One thing that I do want to mention here is that there is no way to adjust the key or iv at runtime using my code, you will have to modify it yourself. They must be adjusted at design time and cannot be changed once the program is implemented. This is due to the environment that I am going to be implementing the software in. The key and block(iv) size are given in bits... This was because different algorithms have different key/iv sizes. Remember this if you decide to create more encryption/decryption algorithms (as I ran into problems, easy to fix, but problems none-the-less). 

Note 1: If you don't want to use the factory at all, you can just copy/paste the encrypt/decrypt functions.
Note 2: In the interest of space, the other algorithms aren't placed here, but they are practically the exact same as this, but using the different .NET objects.


```
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

Public Class Rijndael
    Implements ICrypto

    ' The key and initialization vector : change them for your application
    Private _key() As Byte = {132, 42, 53, 124, 75, 56, 87, 38, 9, 10, 161, 132, 183, _
91, 105, 16, 117, 218, 149, 230, 221, 212, 235, 64}
    Private _iv() As Byte = {83, 71, 26, 58, 54, 35, 22, 11, 83, 71, 26, 58, 54, 35, 22, 11}

    ' returns the default size, in bits of the iv
    Public Function BlockSize() As Integer Implements ICrypto.BlockSize
        Dim aes As New RijndaelManaged()

        Return aes.BlockSize
    End Function

    ' returns the default size, in bits of the key
    Public Function KeySize() As Integer Implements ICrypto.KeySize
        Dim aes As New RijndaelManaged()

        Return aes.KeySize
    End Function

    ' decrypts a string that was encrypted using the Encrypt method
    Public Function Decrypt(ByVal data As String) As String Implements ICrypto.Decrypt
        Try
            Dim inBytes() As Byte = Convert.FromBase64String(data)
            Dim mStream As New MemoryStream(inBytes, 0, inBytes.Length) ' instead of writing the decrypted text

            Dim aes As New RijndaelManaged()
            Dim cs As New CryptoStream(mStream, aes.CreateDecryptor(_key, _iv), CryptoStreamMode.Read)

            Dim sr As New StreamReader(cs)

            Return sr.ReadToEnd()
        Catch ex As Exception
            Throw ex
        End Try
    End Function

    ' Encrypts a given string
    Public Function Encrypt(ByVal data As String) As String Implements ICrypto.Encrypt
        Try
            Dim utf8 As New UTF8Encoding
            Dim inBytes() As Byte = utf8.GetBytes(data) ' ascii encoding uses 7 
'bytes for characters whereas the encryption uses 8 bytes, thus we use utf8
            Dim ms As New MemoryStream() 'instead of writing the encrypted 
'string to a filestream, I will use a memorystream

            Dim aes As New RijndaelManaged()
            Dim cs As New CryptoStream(ms, aes.CreateEncryptor(_key, _iv), CryptoStreamMode.Write)

            cs.Write(inBytes, 0, inBytes.Length) ' encrypt
            cs.FlushFinalBlock()

            Return Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length)
        Catch ex As Exception
            Throw ex
        End Try
    End Function    
End Class
```

Here's the implementation. The first call creates the factor, the second creats the encryption/decryption object and passes the name of the algorithm given from a combobox. The rest is pretty self-explanatory.


```
Try
    Dim CryptographyFactory As New CryptoFactory()
    Dim Cryptographer As ICrypto = CryptographyFactory.MakeCryptographer(cboEncryption.SelectedItem)

    Dim etext As String = Cryptographer.Encrypt(txtInput.Text.ToString)
    txtEOutput.Text = etext

    Dim dtext As String = Cryptographer.Decrypt(etext)
    txtDOutput.Text = dtext
Catch ex As Exception
    MessageBox.Show(ex.Message, "Encryption Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
```

Hope it clears up any wonders about symmetric encryption/decryption using .NET.

----------


## Snow_teo

Hi. Just to ask you whether you know how to solve my problem? I'm using your Symmetric code and for the encryption part is alright but when it come to decrpytion that is problem. I think the problem lies with the red colour codes. I'm using the codes in An ASP.Net web Application using vb.net. 

I am wondering if base64 is not supported becoz it will posted an error msg when run. Error:Invalid character in a Base-64 string. So I changed to UTF8 but still there's Error:Length of the data to decrypt is invalid. Why is it so, do you have any solution for me?

Below are my edited codes:



```
#Region "Import Libraries"

Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

#End Region

Public Class Rijndael   'AES Encrypt

    ' The key and initialization vector : change them for your application
    Private Shared _key() As Byte = {43, 126, 21, 22, 40, 82, 46, 90, 85, 9, 21, 120, 9, 49, 79, 60}
    Private Shared _iv() As Byte = {83, 71, 26, 58, 54, 35, 22, 11, 83, 71, 26, 58, 54, 35, 22, 11}

    ' returns the default size, in bits of the iv
    Public Function BlockSize() As Integer
        Dim aes As New RijndaelManaged()

        Return aes.BlockSize
    End Function

    ' returns the default size, in bits of the key
    Public Function KeySize() As Integer
        Dim aes As New RijndaelManaged()

        Return aes.KeySize
    End Function

    ' decrypts a string that was encrypted using the Encrypt method

    Public Shared Function Decrypt(ByVal data As String) As String
        If (data.StartsWith("<packet>")) Then
            data = data.Replace("<packet>", "")
            data = data.Replace("</packet>", "")
        End If

        Try
            'Dim inBytes() As Byte = Convert.FromBase64String(data)
            Dim utf8 As New UTF8Encoding
            Dim inBytes() As Byte = utf8.GetBytes(data) ' ascii encoding uses 7 
            
            Dim mStream As New MemoryStream(inBytes, 0, inBytes.Length) ' instead of writing the decrypted text

            Dim aes As New RijndaelManaged()
            Dim cs As New CryptoStream(mStream, aes.CreateDecryptor(_key, _iv), CryptoStreamMode.Read)

            Dim sr As New StreamReader(cs)

            Return ("<packet>" + sr.ReadToEnd() + "</packet>") 'Pass the decrypted message to the application

        Catch ex As Exception
            Throw ex
        End Try
    End Function


    ' Encrypts a given string
    Public Shared Function Encrypt(ByVal data As String) As String
        Try
            Dim utf8 As New UTF8Encoding
            Dim inBytes() As Byte = utf8.GetBytes(data) ' ascii encoding uses 7 
            'bytes for characters whereas the encryption uses 8 bytes, thus we use utf8
            Dim ms As New MemoryStream() 'instead of writing the encrypted 
            'string to a filestream, I will use a memorystream

            Dim aes As New RijndaelManaged()
            Dim cs As New CryptoStream(ms, aes.CreateEncryptor(_key, _iv), CryptoStreamMode.Write)

            cs.Write(inBytes, 0, inBytes.Length) ' Start encrypt
            cs.FlushFinalBlock() ' finish encrypt

            Return Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length)
        Catch ex As Exception
            Throw ex
        End Try
    End Function
End Class
```

----------


## Dearbhavin

Thanks a lot it is working 100 percent accurate without any error. 
Cool and happy  :Thumb:  
*Thanks a lot*
Bhavin

----------


## jsweeney

One question: Isn't your factory a concrete one as opposed to an abstract one?

I used the code provided as a basis to create a more flexible set of classes.

First, I renamed the interface to ICryptographer.

Second, I created a class named Cryptographer that implements ICryptographer. The New method takes any SymmetricAlgorithm instance as a parameter. In this way, you can use the concrete factory to instantiate the Cryptographer class using any symmetric algorithm you choose.

Third, the concrete factory instantiates the requested SymmetricAlgorithm, then instantiates the Cryptographer class, passing in the SymmetricAlgorithm.

Here is all the code:



```
Public Interface ICryptographer

    Function Encrypt(ByVal data As String) As String
    Function Decrypt(ByVal data As String) As String

End Interface

Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Imports BaseClasses

Public Class Cryptographer
    Implements ICryptographer

    Private mSymmetricAlgorithm As SymmetricAlgorithm
    Private mMemoryStream As MemoryStream
    Private plainBytes As Byte()
    Private encryptedBytes() As Byte


    Private key() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}

    Private iv() As Byte = {1, 2, 3, 4, 5, 6, 7, 8}

    Public Sub New(ByVal pSymmetricAlgorithm As SymmetricAlgorithm)

        mSymmetricAlgorithm = pSymmetricAlgorithm
        mSymmetricAlgorithm.Key = Me.key
        mSymmetricAlgorithm.IV = Me.iv

    End Sub

    Protected Overrides Sub Finalize()
        mSymmetricAlgorithm = Nothing
        mMemoryStream = Nothing
        plainBytes = Nothing
        encryptedBytes = Nothing
        MyBase.Finalize()
    End Sub

    Public Function Encrypt(ByVal data As String) As String Implements ICryptographer.Encrypt
        Dim encStream As CryptoStream

        Try

            plainBytes = Encoding.UTF8.GetBytes(data)
            mMemoryStream = New MemoryStream((data.Length * 2) - 1)
            encStream = New CryptoStream(mMemoryStream, mSymmetricAlgorithm.CreateEncryptor(), CryptoStreamMode.Write)
            encStream.Write(plainBytes, 0, plainBytes.Length)
            encStream.FlushFinalBlock()
            ReDim encryptedBytes(CInt(mMemoryStream.Length - 1))
            mMemoryStream.Position = 0
            mMemoryStream.Read(encryptedBytes, 0, CInt(mMemoryStream.Length))
            encStream.Close()
            Return Convert.ToBase64String(encryptedBytes)

        Catch ex As Exception

            Throw

        Finally

            encStream = Nothing

        End Try

    End Function

    Public Function Decrypt(ByVal data As String) As String Implements ICryptographer.Decrypt
        Dim decStream As Security.Cryptography.CryptoStream

        Try

            encryptedBytes = Convert.FromBase64String(data)
            mMemoryStream = New IO.MemoryStream((data.Length * 2) - 1)
            decStream = New CryptoStream(mMemoryStream, mSymmetricAlgorithm.CreateDecryptor(), CryptoStreamMode.Write)
            decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
            decStream.FlushFinalBlock()
            ReDim plainBytes(CInt(mMemoryStream.Length - 1))
            mMemoryStream.Position = 0
            mMemoryStream.Read(plainBytes, 0, CInt(mMemoryStream.Length))
            decStream.Close()
            Return Encoding.UTF8.GetString(plainBytes)

        Catch ex As Exception

            Throw

        Finally

            decStream = Nothing

        End Try

    End Function

End Class

Imports BaseClasses
Imports System.Security.Cryptography

Public Class Factory

    Public Shared Function GetCryptographer(ByVal CryptographerType As String) As ICryptographer
        Dim pSymmetricAlgorithm As SymmetricAlgorithm = Nothing

        Try

            Select Case CryptographerType.ToLower

                Case "des"
                    pSymmetricAlgorithm = New DESCryptoServiceProvider
                Case "tripledes"
                    pSymmetricAlgorithm = New TripleDESCryptoServiceProvider
                Case "rijndeal"
                    pSymmetricAlgorithm = New RijndaelManaged
                Case Else

            End Select

            Return New Cryptographer(pSymmetricAlgorithm)

        Catch ex As Exception

            Throw

        End Try

    End Function

End Class
```

----------


## petka

Hey jsweeney, 

I've got a couple of question regarding to encrypting and decrypting. I've used this class in my application, it seems, it's working, but the thing im thinking about is why every string is "coded" in the same way ? 

I thought, that with AES each time we code the same string, the output differs ?

----------


## cholixs

sorry,i'm newbie about this,what about the cast-128 and cast-256 source code?

----------

