Imports Microsoft.VisualBasic
Imports System.Security.Cryptography

' issue 26553

''' <summary>
''' Class to handle the encryption process using Rijndael AES encryption with a 32-byte
''' key and 16 byte init vector.
''' </summary>
''' <remarks></remarks>
Public Class EncryptionHandler

    ' keyPhrase MUST be 32 char.  share with NextIT for decryption
    '---------------------------------------12345678901234567890123456789012
    Private Shared m_KeyPhrase As String = "sMzF#fGrwIR/UkEiq6lw/A==7$ge@1&L"
    ' InitVector MUST be 16 char
    '----------------------------------------1234567890123456
    Private Shared m_InitVector As String = "Fd4wg5YIJ+bj4Kw%"

    ''' <summary>
    ''' Encrypt a string
    ''' </summary>
    ''' <param name="plainTextInput">String to be encrypted</param>
    ''' <returns>Encrypted version of input string</returns>
    ''' <remarks></remarks>
    Public Shared Function Encrypt(plainTextInput As String) As String

        ' Convert strings into byte arrays. 
        ' Let us assume that strings only contain ASCII codes. 
        ' If strings include Unicode characters, use Unicode, UTF7, or UTF8  
        ' encoding. 
        Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(m_InitVector)
        Dim keyBytes As Byte() = Encoding.ASCII.GetBytes(m_KeyPhrase)
        ' Convert our plaintext into a byte array. 
        ' Let us assume that plaintext contains UTF8-encoded characters. 
        Dim plainTextBytes As Byte() = Encoding.UTF8.GetBytes(plainTextInput)

        Dim symmetricKey As New RijndaelManaged()
        Dim encryptor As ICryptoTransform
        ' Define memory stream which will be used to hold encrypted data. 
        Dim memoryStream As New IO.MemoryStream()
        Dim cryptStream As CryptoStream
        Dim cipherTextBytes As Byte()
        Dim cipherText As String

        symmetricKey.Mode = CipherMode.CBC

        ' Generate encryptor from the existing key bytes and initialization  
        ' vector. Key size will be defined based on the number of the key  
        ' bytes. 
        encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)

        ' Build cryptographic stream (always use Write mode for encryption). 
        cryptStream = New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)

        ' Do the encryption
        cryptStream.Write(plainTextBytes, 0, plainTextBytes.Length)
        cryptStream.FlushFinalBlock()

        ' Convert our encrypted data from a memory stream into a byte array. 
        cipherTextBytes = memoryStream.ToArray()

        memoryStream.Close()
        cryptStream.Close()

        ' Convert encrypted data into a base64-encoded string. 
        cipherText = Convert.ToBase64String(cipherTextBytes)

        Return cipherText

    End Function

    ''' <summary>
    ''' Decrypt a string
    ''' </summary>
    ''' <param name="encodedTextInput">Encrypted string to be decrypted</param>
    ''' <returns>Decrypted string</returns>
    ''' <remarks>This is not actually used, but is shown as a demo/proof of concept as to
    ''' how NextIT will have to decipher this encrypted string value.</remarks>
    ''' <remarks></remarks>
    Public Shared Function Decrypt(encodedTextInput As String) As String

        ' Convert strings defining encryption key characteristics into byte 
        ' arrays. Let us assume that strings only contain ASCII codes. 
        ' If strings include Unicode characters, use Unicode, UTF7, or UTF8 
        ' encoding. 
        Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(m_InitVector)
        Dim keyBytes As Byte() = Encoding.ASCII.GetBytes(m_KeyPhrase)
        ' Convert our ciphertext into a byte array.
        Dim cipherTextBytes As Byte() = Convert.FromBase64String(encodedTextInput)
        ' Create uninitialized Rijndael encryption object.
        Dim symmetricKey As New RijndaelManaged()
        Dim decryptor As ICryptoTransform
        Dim memoryStream As IO.MemoryStream
        Dim cryptStream As CryptoStream
        Dim plainTextBytes As Byte()
        Dim decryptedByteCount As Integer
        Dim plainText As String

        symmetricKey.Mode = CipherMode.CBC

        ' Generate decryptor from the existing key bytes and initialization 
        ' vector. Key size will be defined based on the number of the key 
        ' bytes.
        decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)

        ' Define memory stream which will be used to hold encrypted data.
        memoryStream = New IO.MemoryStream(cipherTextBytes)
        ' Define cryptographic stream (always use Read mode for decryption).
        cryptStream = New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)

        ' Since at this point we don't know what the size of decrypted data
        ' will be, allocate the buffer long enough to hold ciphertext;
        ' plaintext is never longer than ciphertext.
        plainTextBytes = New Byte(cipherTextBytes.Length - 1) {}

        ' Do the decryption
        decryptedByteCount = cryptStream.Read(plainTextBytes, 0, plainTextBytes.Length)

        memoryStream.Close()
        cryptStream.Close()

        ' Convert decrypted data into a string. 
        ' Let us assume that the original plaintext string was UTF8-encoded.
        plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount)

        Return plainText
    End Function

End Class