﻿'CREATED BY tassa FOR VBFORUMS.COM
'August/31/2009
'IF YOU ARE GOING TO DISTRIBUTE,
'POST THIS CODE IN ANY OTHER ONLINE SERVICE,
'WEBSITE, ETC, GIVE THE NECESSARY CREDITS!
'Thanks :)

Imports System.Security.Cryptography
Imports System.Text
Imports System.IO

Namespace SymmetricEncryptionAlgorithms
#Region " Rijndael Encryption Algorithm "
    Public Class RijndaelManagedEncryption

#Region " Global Variables "
        'The encoding used to get a byte array from the given string.
        Private Shared encoding As New UTF8Encoding
        'The encryption algorithm.
        Private Shared RijndaelAlg As New RijndaelManaged
        'The hash algorithm to generate a 32 byte hash from the given key.
        Private Shared HashAlg As HashAlgorithm = New SHA256Managed
        'An enumeration containing a cryptographic action.
        Enum RijndaelCryptographicAction
            Encrypt = 0
            Decrypt = 1
        End Enum
#End Region

#Region " Encryption/Decryption Events "
        ''' <summary>
        ''' Implements a cryptographic action using RijndaelManaged.
        ''' </summary>
        ''' <param name="text">
        ''' The string to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function RijndaelEncryptDecrypt(ByVal text As String, ByVal key As String, _
                                                        ByVal action As RijndaelCryptographicAction) As String
            Dim textBytes As Byte() = encoding.GetBytes(text)
            Dim keyBytes As Byte() = CheckKey(key)

            Return RijndaelEncryptDecrypt(textBytes, keyBytes, action)
        End Function

        ''' <summary>
        ''' Implements a cryptographic action using RijndaelManaged.
        ''' </summary>
        ''' <param name="text">
        ''' The string to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function RijndaelEncryptDecrypt(ByVal text As String, ByVal key As Byte(), _
                                                        ByVal action As RijndaelCryptographicAction) As String
            Dim textBytes As Byte() = encoding.GetBytes(text)
            Dim keyBytes As Byte() = CheckKey(key)

            Return RijndaelEncryptDecrypt(textBytes, keyBytes, action)
        End Function

        ''' <summary>
        ''' Implements a cryptographic action using RijndaelManaged.
        ''' </summary>
        ''' <param name="data">
        ''' The string bytes to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function RijndaelEncryptDecrypt(ByVal data As Byte(), ByVal key As String, _
                                                        ByVal action As RijndaelCryptographicAction) As String
            Dim keyBytes As Byte() = CheckKey(key)

            Return RijndaelEncryptDecrypt(data, keyBytes, action)
        End Function

        ''' <summary>
        ''' Implements a cryptographic action using RijndaelManaged.
        ''' </summary>
        ''' <param name="data">
        ''' The string bytes to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function RijndaelEncryptDecrypt(ByVal data As Byte(), ByVal key As Byte(), _
                                                        ByVal action As RijndaelCryptographicAction) As String
            RijndaelAlg.BlockSize = 256

            If Not key.Length = 32 Then
                key = CheckKey(key)
            End If

            Dim IV As Byte() = GenerateIV(key)
            Try
                Select Case action
                    Case RijndaelCryptographicAction.Encrypt
                        Using memStream As New MemoryStream
                            Using cStream As New CryptoStream(memStream, _
                                                       RijndaelAlg.CreateEncryptor(key, IV), _
                                                       CryptoStreamMode.Write)
                                cStream.Write(data, 0, data.Length)
                            End Using
                            Return Convert.ToBase64String(memStream.ToArray)
                        End Using

                    Case RijndaelCryptographicAction.Decrypt
                        Dim textBytes As Byte() = Convert.FromBase64String(encoding.GetString(data))
                        Using memStream As New MemoryStream(textBytes)
                            Dim decryptedData(textBytes.Length) As Byte
                            Using cStream As New CryptoStream(memStream, _
                                                       RijndaelAlg.CreateDecryptor(key, IV), _
                                                       CryptoStreamMode.Read)
                                cStream.Read(decryptedData, 0, decryptedData.Length)
                            End Using
                            Return encoding.GetString(decryptedData)
                        End Using

                    Case Else
                        Return Nothing
                End Select

            Catch ex As CryptographicException
                Return "Error - Invalid Password"
            End Try
        End Function
#End Region

        'Generate a byte array containing the generated hash from the given key.
#Region " Key Check "
        Private Overloads Shared Function CheckKey(ByVal key As String) As Byte()
            Dim byteKey As Byte() = encoding.GetBytes(key)

            Return CheckKey(byteKey)
        End Function

        Private Overloads Shared Function CheckKey(ByVal key As Byte()) As Byte()
            Return HashAlg.ComputeHash(key)
        End Function
#End Region

        'Generate a byte array containing the generated IV from the given key.
#Region " Generate IV "
        Private Overloads Shared Function GenerateIV(ByVal key As String) As Byte()
            Dim keyBytes As Byte() = encoding.GetBytes(key)

            Return GenerateIV(keyBytes)
        End Function

        Private Overloads Shared Function GenerateIV(ByVal key As Byte()) As Byte()
            Dim keyReverse As String = encoding.GetString(key).ToCharArray.Reverse.ToString
            Dim NewKey As Byte() = encoding.GetBytes(keyReverse)

            Return HashAlg.ComputeHash(NewKey)
        End Function
#End Region
    End Class
#End Region

#Region " AES Encryption Algorithm "
    Public Class AESManagedEncryption

#Region " Global Variables "
        'The encoding used to get a byte array from the given string.
        Private Shared encoding As New UTF8Encoding
        'The encryption algorithm.
        Private Shared AESAlg As New AesManaged
        'The hash algorithm to generate a 32 byte hash from the given key.
        Private Shared HashAlg As HashAlgorithm = New SHA256Managed
        'An enumeration containing a cryptographic action.
        Enum AESCryptographicAction
            Encrypt = 0
            Decrypt = 1
        End Enum
#End Region

#Region " Encryption/Decryption Events "
        ''' <summary>
        ''' Implements a cryptographic action using AESManaged.
        ''' </summary>
        ''' <param name="text">
        ''' The string to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function AESEncryptDecrypt(ByVal text As String, ByVal key As String, _
                                                        ByVal action As AESCryptographicAction) As String
            Dim textBytes As Byte() = encoding.GetBytes(text)
            Dim keyBytes As Byte() = CheckKey(key)

            Return AESEncryptDecrypt(textBytes, keyBytes, action)
        End Function

        ''' <summary>
        ''' Implements a cryptographic action using AESManaged.
        ''' </summary>
        ''' <param name="text">
        ''' The string to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function AESEncryptDecrypt(ByVal text As String, ByVal key As Byte(), _
                                                        ByVal action As AESCryptographicAction) As String
            Dim textBytes As Byte() = encoding.GetBytes(text)
            Dim keyBytes As Byte() = CheckKey(key)

            Return AESEncryptDecrypt(textBytes, keyBytes, action)
        End Function

        ''' <summary>
        ''' Implements a cryptographic action using AESManaged.
        ''' </summary>
        ''' <param name="data">
        ''' The string bytes to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function AESEncryptDecrypt(ByVal data As Byte(), ByVal key As String, _
                                                        ByVal action As AESCryptographicAction) As String
            Dim keyBytes As Byte() = CheckKey(key)

            Return AESEncryptDecrypt(data, keyBytes, action)
        End Function

        ''' <summary>
        ''' Implements a cryptographic action using AESManaged.
        ''' </summary>
        ''' <param name="data">
        ''' The string bytes to be encrypted/decrypted.</param>
        ''' <param name="key">
        ''' The key used to perform the cryptographic action.</param>
        ''' <param name="action">
        ''' The cryptographic action to perform.</param>
        ''' <returns>A string array containing the encrypted/decrypted data.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function AESEncryptDecrypt(ByVal data As Byte(), ByVal key As Byte(), _
                                                        ByVal action As AESCryptographicAction) As String
            If Not key.Length = 32 Then
                key = CheckKey(key)
            End If

            Dim IV As Byte() = GenerateIV(key)
            Try
                Select Case action
                    Case AESCryptographicAction.Encrypt
                        Using memStream As New MemoryStream
                            Using cStream As New CryptoStream(memStream, _
                                                       AESAlg.CreateEncryptor(key, IV), _
                                                       CryptoStreamMode.Write)
                                cStream.Write(data, 0, data.Length)
                            End Using
                            Return Convert.ToBase64String(memStream.ToArray)
                        End Using

                    Case AESCryptographicAction.Decrypt
                        Dim textBytes As Byte() = Convert.FromBase64String(encoding.GetString(data))
                        Using memStream As New MemoryStream(textBytes)
                            Dim decryptedData(textBytes.Length) As Byte
                            Using cStream As New CryptoStream(memStream, _
                                                       AESAlg.CreateDecryptor(key, IV), _
                                                       CryptoStreamMode.Read)
                                cStream.Read(decryptedData, 0, decryptedData.Length)
                            End Using
                            Return encoding.GetString(decryptedData)
                        End Using

                    Case Else
                        Return Nothing
                End Select

            Catch ex As CryptographicException
                Return "Error - Invalid Password"
            End Try
        End Function
#End Region

        'Generate a byte array containing the generated hash from the given key.
#Region " Key Check "
        Private Overloads Shared Function CheckKey(ByVal key As String) As Byte()
            Dim byteKey As Byte() = encoding.GetBytes(key)

            Return CheckKey(byteKey)
        End Function

        Private Overloads Shared Function CheckKey(ByVal key As Byte()) As Byte()
            Return HashAlg.ComputeHash(key)
        End Function
#End Region

        'Generate a byte array containing the generated IV from the given key.
#Region " Generate IV "
        Private Overloads Shared Function GenerateIV(ByVal key As String) As Byte()
            Dim keyBytes As Byte() = encoding.GetBytes(key)

            Return GenerateIV(keyBytes)
        End Function

        Private Overloads Shared Function GenerateIV(ByVal key As Byte()) As Byte()
            Dim keyReverse As String = encoding.GetString(key).ToCharArray.Reverse.ToString
            Dim NewKey As Byte() = HashAlg.ComputeHash(encoding.GetBytes(keyReverse))
            Dim FinalKey(15) As Byte
            'The number of bytes to copy is 16, but the length of the array
            'has to be 15, since it starts at 0.
            Array.Copy(NewKey, FinalKey, 15)

            Return FinalKey
        End Function
#End Region
    End Class
#End Region
End Namespace

Namespace SHAManagedHash
    ''' <summary>
    ''' Computes the  SHA256 hash for the input data using the managed library. 
    ''' </summary>
    ''' <remarks></remarks>
#Region " SHA256 Hash "
    Public Class SHA256ManagedHash

#Region " Global Variables "
        'The encoding to get the byte array from the given data.
        Private Shared _encoding As New UTF8Encoding
        'The hash algorithm.
        Private Shared hashAlg As New SHA256Managed
#End Region
        'Please note that I'm using Overloads.
        'I have chosen to do it this way since it's clearer
        'and it's more "flexible".
#Region " SHA256 Hash Events "
        'I'm using ByRef salt as Byte(), so that the orignal variable will hold the
        'generated salt, so that it can be saved, edited, etc.
        ''' <summary>
        ''' Computes the SHA256 hash for the input data. 
        ''' </summary>
        ''' <param name="text">
        ''' The text to be hashed.
        ''' </param>
        ''' <param name="salt">
        ''' The byte array that will hold the generated salt.</param>
        ''' <returns>Returns a base 64 string.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function SHA256StringHash(ByVal text As String, ByRef salt As Byte()) As String
            Dim textBytes As Byte() = _encoding.GetBytes(text)
            Dim myrandom As New Random
            Dim rng As New RNGCryptoServiceProvider

            salt = New Byte(myrandom.Next(4, 8)) {}
            rng.GetNonZeroBytes(salt)
            Dim SaltedText_Byte As Byte() = New Byte((textBytes.Length + salt.Length) - 1) {}
            SaltedText_Byte = textBytes.Concat(salt).ToArray
            'It "returns" to the third overload (actually sends, but whatever :P) 
            'the generated byte array,
            'which holds the text and the salt's byte array.
            Return SHA256StringHash(SaltedText_Byte)
        End Function

        ''' <summary>
        ''' Computes the SHA256 hash for the input data. 
        ''' </summary>
        ''' <param name="text">
        ''' The text to be hashed.
        ''' </param>
        ''' <returns>Returns a base 64 string.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function SHA256StringHash(ByVal text As String) As String
            'Get the text's byte array and sends it to the third overload.
            Dim textBytes As Byte() = _encoding.GetBytes(text)
            Return SHA256StringHash(textBytes)
        End Function

        ''' <summary>
        ''' Computes the SHA256 hash for the input data. 
        ''' </summary>
        ''' <param name="data">
        ''' The byte array to be hashed.</param>
        ''' <returns>Returns a base 64 string.</returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function SHA256StringHash(ByVal data As Byte()) As String
            'Compute the hash from the received byte array and returns it
            'to the calling method.
            Dim hashedData As Byte() = hashAlg.ComputeHash(data)
            Return Convert.ToBase64String(hashedData)
        End Function
#End Region

#Region " Verify Hash "

        ''' <summary>
        ''' Verifies a given string against a stored hash value.
        ''' </summary>
        ''' <param name="text">
        ''' The text to be compared against the stored hash value.
        ''' </param>
        ''' <param name="hash">
        ''' The stored hash value to be compared against the given string.
        ''' </param>
        ''' <param name="salt">
        ''' The stored salt value.
        ''' </param>
        ''' <returns>Returns a boolean depending if it is a match or not.
        ''' </returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function VerifyHash(ByVal text As String, ByVal hash As String, ByVal salt As Byte()) As Boolean
            Dim textBytes As Byte() = _encoding.GetBytes(text)
            Dim hashByte As Byte() = Convert.FromBase64String(hash)

            Return VerifyHash(textBytes, hashByte, salt)
        End Function

        ''' <summary>
        ''' Verifies a given string against a stored hash value.
        ''' </summary>
        ''' <param name="data">
        ''' The byte array of the string to be compared against the stored hash value.
        ''' </param>
        ''' <param name="hash">
        ''' The stored hash value to be compared against the given string.
        ''' </param>
        ''' <param name="salt">
        ''' The stored salt value.
        ''' </param>
        ''' <returns>Returns a boolean depeding if it is a match or not.
        ''' </returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function VerifyHash(ByVal data As Byte(), ByVal hash As String, ByVal salt As Byte()) As Boolean
            Dim hashBytes As Byte() = _encoding.GetBytes(hash)

            Return VerifyHash(data, hashBytes, salt)
        End Function

        ''' <summary>
        ''' Verifies a given string against a stored hash value.
        ''' </summary>
        ''' <param name="text">
        ''' The text to be compared against the stored hash value.
        ''' </param>
        ''' <param name="hash">
        ''' The stored value hash to be compared against the given text.
        ''' </param>
        ''' <param name="salt">
        ''' The stored salt value.
        ''' </param>
        ''' <returns>Returns a boolean depending if it is a match or not.
        ''' </returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function VerifyHash(ByVal text As String, ByVal hash As String, ByVal salt As String) As Boolean
            Dim textBytes As Byte() = _encoding.GetBytes(text)
            Dim hashBytes As Byte() = _encoding.GetBytes(hash)
            Dim saltBytes As Byte() = _encoding.GetBytes(salt)

            Return VerifyHash(textBytes, hashBytes, saltBytes)
        End Function

        ''' <summary>
        ''' Verifies a given string against a stored hash value.
        ''' </summary>
        ''' <param name="data">
        ''' The byte array of the string to be compared against the stored hash value.
        ''' </param>
        ''' <param name="hash">
        ''' The stored hash value to be compared against the given string.
        ''' </param>
        ''' <param name="salt">
        ''' The stored salt value.
        ''' </param>
        ''' <returns>Returns a boolean depeding if it is a match or not.
        ''' </returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function VerifyHash(ByVal data As Byte(), ByVal hash As Byte(), ByVal salt As Byte()) As Boolean
            Dim hashCheck((data.Length + salt.Length) - 1) As Byte
            hashCheck = data.Concat(salt).ToArray
            Dim verify As Byte() = hashAlg.ComputeHash(hashCheck)
            Dim IsMatch As Boolean = False
            For i As Integer = 0 To verify.Length - 1
                If verify(i) = hash(i) Then
                    IsMatch = True
                Else
                    IsMatch = False
                End If
            Next
            Return IsMatch
        End Function
#End Region
    End Class
#End Region
End Namespace