Imports System.Security.Cryptography
Imports System.Runtime.InteropServices
Dim Key As Byte() = System.Text.Encoding.UTF8.GetBytes("verysecretpassword")
Dim TextToEncrypt As String = "Hello World! How are you?"
Dim DataToEncrypt As Byte() = System.Text.Encoding.UTF8.GetBytes(TextToEncrypt)
Console.WriteLine("== Text to encrypt ==" & Environment.NewLine & TextToEncrypt)
EncryptFile("encrypted.txt", DataToEncrypt, Key)
Dim EncryptedData As Byte() = File.ReadAllBytes("encrypted.txt")
Dim EncryptedText As String = System.Text.Encoding.UTF8.GetString(EncryptedData).Replace(Convert.ToChar(0).ToString(), "[NUL]")
Console.WriteLine("== Encrypted text ==" & Environment.NewLine & EncryptedText)
Dim DecryptedData As Byte() = DecryptFile("encrypted.txt", Key)
Dim DecryptedText As String = System.Text.Encoding.UTF8.GetString(DecryptedData)
Console.WriteLine("== Decrypted text ==" & Environment.NewLine & DecryptedText)
Public Sub EncryptFile(ByVal File As String, ByVal Data As Byte(), ByVal Key As Byte())
Using OutputStream As New FileStream(File, FileMode.Create, FileAccess.Write, FileShare.None)
Using AesStream As Aes256Stream = Aes256Stream.CreateEncryptionStream(OutputStream, Key)
AesStream.Write(Data, 0, Data.Length)
Public Function DecryptFile(ByVal File As String, ByVal Key As Byte()) As Byte()
Using InputStream As New FileStream(File, FileMode.Open, FileAccess.Read, FileShare.Read)
Using DecryptedStream As New MemoryStream
Using AesStream As Aes256Stream = Aes256Stream.CreateDecryptionStream(InputStream, Key)
Dim Buffer As Byte() = New Byte(4096 - 1) {}
While AesStream.Position < AesStream.Length
Dim BytesRead As Integer = AesStream.Read(Buffer, 0, Buffer.Length)
DecryptedStream.Write(Buffer, 0, BytesRead)
Return DecryptedStream.ToArray()
Public Class Aes256Stream
Private _underlyingStream As Stream
Private AES As RijndaelManaged
Private Transform As ICryptoTransform
Public ReadOnly Property BlockSize As Integer
Public ReadOnly Property KeySize As Integer
Public Overrides ReadOnly Property Length As Long
Return _underlyingStream.Length
Public Overrides Property Position As Long
If _underlyingStream.CanSeek = False Then Throw New NotSupportedException("The underlying stream doesn't support seeking!")
Return _underlyingStream.Position
If _underlyingStream.CanSeek = False Then Throw New NotSupportedException("The underlying stream doesn't support seeking!")
_underlyingStream.Position = value
Public ReadOnly Property UnderlyingStream As Stream
Private Sub New(ByVal UnderlyingStream As Stream, _
ByVal AES As RijndaelManaged, _
ByVal CryptoTransform As ICryptoTransform, _
ByVal Mode As CryptoStreamMode)
MyBase.New(UnderlyingStream, CryptoTransform, Mode)
Me._underlyingStream = UnderlyingStream
Me.Transform = CryptoTransform
Public Overrides Sub SetLength(value As Long)
_underlyingStream.SetLength(value)
Public Shared Function CreateEncryptionStream(ByVal UnderlyingStream As Stream, ByVal Key As Byte()) As Aes256Stream
Dim AES As New RijndaelManaged
AES.Key = Aes256Stream.PadOrTruncate(Key, AES.KeySize / 8)
AES.Mode = CipherMode.CBC
AES.Padding = PaddingMode.PKCS7
If UnderlyingStream.CanWrite = True Then
Dim LengthIV As Byte() = BitConverter.GetBytes(AES.IV.Length)
UnderlyingStream.Write(LengthIV, 0, LengthIV.Length)
UnderlyingStream.Write(AES.IV, 0, AES.IV.Length)
Throw New IOException("Underlying stream is not writable!")
Return New Aes256Stream(UnderlyingStream, AES, AES.CreateEncryptor(), CryptoStreamMode.Write)
Public Shared Function CreateDecryptionStream(ByVal UnderlyingStream As Stream, ByVal Key As Byte()) As Aes256Stream
Dim AES As New RijndaelManaged
AES.Key = Aes256Stream.PadOrTruncate(Key, AES.KeySize / 8)
If UnderlyingStream.CanRead = True Then
Dim BytesReadIV As Integer = 0
Dim BufferIV As Byte() = New Byte(Marshal.SizeOf(GetType(Integer)) - 1) {}
While BytesReadIV < BufferIV.Length
Dim BytesRead As Integer = UnderlyingStream.Read(BufferIV, BytesReadIV, BufferIV.Length - BytesReadIV)
If BytesRead = 0 AndAlso BytesReadIV < BufferIV.Length Then _
Throw New IOException("End of stream reached before IV could be parsed!")
LengthIV = BitConverter.ToInt32(BufferIV, 0)
BufferIV = New Byte(LengthIV - 1) {}
While BytesReadIV < BufferIV.Length
Dim BytesRead As Integer = UnderlyingStream.Read(BufferIV, BytesReadIV, BufferIV.Length - BytesReadIV)
If BytesRead = 0 AndAlso BytesReadIV < BufferIV.Length Then _
Throw New IOException("End of stream reached before IV could be parsed!")
Throw New IOException("Underlying stream is not readable!")
AES.Mode = CipherMode.CBC
AES.Padding = PaddingMode.PKCS7
Return New Aes256Stream(UnderlyingStream, AES, AES.CreateDecryptor(), CryptoStreamMode.Read)
Private Shared Function PadOrTruncate(ByVal Input As Byte(), ByVal PreferredLength As Integer) As Byte()
If Input.Length < PreferredLength Then
Dim PreviousLength As Integer = Input.Length
Array.Resize(Input, Input.Length + (PreferredLength - Input.Length))
For i = PreviousLength To Input.Length - 1
ElseIf Input.Length > PreferredLength Then
Array.Resize(Input, PreferredLength)
Protected Overrides Sub Dispose(disposing As Boolean)
MyBase.Dispose(disposing)
If Transform IsNot Nothing Then
If AES IsNot Nothing Then