732 lines
25 KiB
VB.net
732 lines
25 KiB
VB.net
Imports System.IO
|
|
Imports System.Security.Cryptography
|
|
Imports System.Text
|
|
|
|
Namespace EncryptionUtils
|
|
|
|
#Region " Hash "
|
|
|
|
''' <summary>
|
|
''' Hash functions are fundamental to modern cryptography. These functions map binary
|
|
''' strings of an arbitrary length to small binary strings of a fixed length, known as
|
|
''' hash values. A cryptographic hash function has the property that it is computationally
|
|
''' infeasible to find two distinct inputs that hash to the same value. Hash functions
|
|
''' are commonly used with digital signatures and for data integrity.
|
|
''' </summary>
|
|
Public Class Hasher
|
|
|
|
''' <summary>
|
|
''' Type of hash; some are security oriented, others are fast and simple
|
|
''' </summary>
|
|
Friend Enum Provider
|
|
''' <summary>
|
|
''' Secure Hashing Algorithm provider, SHA-1 variant, 160-bit
|
|
''' </summary>
|
|
SHA1
|
|
''' <summary>
|
|
''' Secure Hashing Algorithm provider, SHA-2 variant, 256-bit
|
|
''' </summary>
|
|
SHA256
|
|
''' <summary>
|
|
''' Secure Hashing Algorithm provider, SHA-2 variant, 384-bit
|
|
''' </summary>
|
|
SHA384
|
|
''' <summary>
|
|
''' Secure Hashing Algorithm provider, SHA-2 variant, 512-bit
|
|
''' </summary>
|
|
SHA512
|
|
''' <summary>
|
|
''' Message Digest algorithm 5, 128-bit
|
|
''' </summary>
|
|
MD5
|
|
End Enum
|
|
|
|
Private _Hash As HashAlgorithm
|
|
Private _HashValue As New Data
|
|
|
|
Friend Sub New()
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Instantiate a new hash of the specified type
|
|
''' </summary>
|
|
Friend Sub New(ByVal p As Provider)
|
|
Select Case p
|
|
Case Provider.MD5
|
|
_Hash = MD5.Create()
|
|
Case Provider.SHA1
|
|
_Hash = SHA1.Create()
|
|
Case Provider.SHA256
|
|
_Hash = SHA256.Create()
|
|
Case Provider.SHA384
|
|
_Hash = SHA384.Create()
|
|
Case Provider.SHA512
|
|
_Hash = SHA512.Create()
|
|
Case Else
|
|
_Hash = SHA256.Create() ' Default to SHA256 for unknown providers
|
|
End Select
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Returns the previously calculated hash
|
|
''' </summary>
|
|
Friend ReadOnly Property Value() As Data
|
|
Get
|
|
Return _HashValue
|
|
End Get
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Calculates hash on a stream of arbitrary length
|
|
''' </summary>
|
|
Friend Function Calculate(ByRef s As System.IO.Stream) As Data
|
|
_HashValue.Bytes = _Hash.ComputeHash(s)
|
|
Return _HashValue
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Calculates hash for fixed length <see cref="Data"/>
|
|
''' </summary>
|
|
Friend Function Calculate(ByVal d As Data) As Data
|
|
Return CalculatePrivate(d.Bytes)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Calculates hash for a string with a prefixed salt value.
|
|
''' A "salt" is random data prefixed to every hashed value to prevent
|
|
''' common dictionary attacks.
|
|
''' </summary>
|
|
Friend Function Calculate(ByVal d As Data, ByVal salt As Data) As Data
|
|
Dim nb(d.Bytes.Length + salt.Bytes.Length - 1) As Byte
|
|
salt.Bytes.CopyTo(nb, 0)
|
|
d.Bytes.CopyTo(nb, salt.Bytes.Length)
|
|
Return CalculatePrivate(nb)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Calculates hash for an array of bytes
|
|
''' </summary>
|
|
Private Function CalculatePrivate(ByVal b() As Byte) As Data
|
|
_HashValue.Bytes = _Hash.ComputeHash(b)
|
|
Return _HashValue
|
|
End Function
|
|
|
|
End Class
|
|
#End Region
|
|
|
|
#Region " Symmetric "
|
|
|
|
''' <summary>
|
|
''' Symmetric encryption uses a single key to encrypt and decrypt.
|
|
''' Both parties (encryptor and decryptor) must share the same secret key.
|
|
''' </summary>
|
|
Friend Class SymmetricEncryptor
|
|
|
|
Private Const _DefaultIntializationVector As String = "%1Az=-@qT"
|
|
Private Const _BufferSize As Integer = 2048
|
|
|
|
Friend Enum Provider
|
|
<Obsolete("MD5 is cryptographically broken and unsuitable for further use. Use SHA256 or stronger.")>
|
|
MD5
|
|
<Obsolete("SHA1 is cryptographically broken and unsuitable for further use. Use SHA256 or stronger.")>
|
|
SHA1
|
|
SHA256
|
|
SHA384
|
|
SHA512
|
|
<Obsolete("DES is cryptographically broken and unsuitable for further use. Use AES instead.")>
|
|
DES
|
|
<Obsolete("RC2 is cryptographically broken and unsuitable for further use. Use AES instead.")>
|
|
RC2
|
|
<Obsolete("Use AES instead. This enum value will be removed in a future version.")>
|
|
Rijndael
|
|
<Obsolete("TripleDES is not recommended for new applications. Use AES instead.")>
|
|
TripleDES
|
|
AES
|
|
End Enum
|
|
|
|
Private _data As Data
|
|
Private _key As Data
|
|
Private _iv As Data
|
|
Private _crypto As SymmetricAlgorithm
|
|
Private _EncryptedBytes As Byte()
|
|
Private _UseDefaultInitializationVector As Boolean
|
|
|
|
Private Sub New()
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Instantiates a new symmetric encryption object using the specified provider.
|
|
''' </summary>
|
|
Friend Sub New(ByVal provider As Provider, Optional ByVal useDefaultInitializationVector As Boolean = True)
|
|
Select Case provider
|
|
Case Provider.DES
|
|
_crypto = DES.Create()
|
|
Case Provider.RC2
|
|
_crypto = RC2.Create()
|
|
Case Provider.Rijndael, Provider.AES
|
|
_crypto = Aes.Create()
|
|
Case Provider.TripleDES
|
|
_crypto = TripleDES.Create()
|
|
Case Else
|
|
_crypto = Aes.Create() ' Default to AES for unknown providers
|
|
End Select
|
|
|
|
'-- make sure key and IV are always set, no matter what
|
|
Me.Key = RandomKey()
|
|
If useDefaultInitializationVector Then
|
|
Me.IntializationVector = New Data(_DefaultIntializationVector)
|
|
Else
|
|
Me.IntializationVector = RandomInitializationVector()
|
|
End If
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Key size in bytes. We use the default key size for any given provider; if you
|
|
''' want to force a specific key size, set this property
|
|
''' </summary>
|
|
Friend Property KeySizeBytes() As Integer
|
|
Get
|
|
Return _crypto.KeySize \ 8
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_crypto.KeySize = Value * 8
|
|
_key.MaxBytes = Value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Key size in bits. We use the default key size for any given provider; if you
|
|
''' want to force a specific key size, set this property
|
|
''' </summary>
|
|
Friend Property KeySizeBits() As Integer
|
|
Get
|
|
Return _crypto.KeySize
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_crypto.KeySize = Value
|
|
_key.MaxBits = Value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' The key used to encrypt/decrypt data
|
|
''' </summary>
|
|
Friend Property Key() As Data
|
|
Get
|
|
Return _key
|
|
End Get
|
|
Set(ByVal Value As Data)
|
|
_key = Value
|
|
_key.MaxBytes = _crypto.LegalKeySizes(0).MaxSize \ 8
|
|
_key.MinBytes = _crypto.LegalKeySizes(0).MinSize \ 8
|
|
_key.StepBytes = _crypto.LegalKeySizes(0).SkipSize \ 8
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Using the default Cipher Block Chaining (CBC) mode, all data blocks are processed using
|
|
''' the value derived from the previous block; the first data block has no previous data block
|
|
''' to use, so it needs an InitializationVector to feed the first block
|
|
''' </summary>
|
|
Friend Property IntializationVector() As Data
|
|
Get
|
|
Return _iv
|
|
End Get
|
|
Set(ByVal Value As Data)
|
|
_iv = Value
|
|
_iv.MaxBytes = _crypto.BlockSize \ 8
|
|
_iv.MinBytes = _crypto.BlockSize \ 8
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' generates a random Initialization Vector, if one was not provided
|
|
''' </summary>
|
|
Friend Function RandomInitializationVector() As Data
|
|
_crypto.GenerateIV()
|
|
Dim d As New Data(_crypto.IV)
|
|
Return d
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' generates a random Key, if one was not provided
|
|
''' </summary>
|
|
Friend Function RandomKey() As Data
|
|
_crypto.GenerateKey()
|
|
Dim d As New Data(_crypto.Key)
|
|
Return d
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Ensures that _crypto object has valid Key and IV
|
|
''' prior to any attempt to encrypt/decrypt anything
|
|
''' </summary>
|
|
Private Sub ValidateKeyAndIv(ByVal isEncrypting As Boolean)
|
|
If _key.IsEmpty Then
|
|
If isEncrypting Then
|
|
_key = RandomKey()
|
|
Else
|
|
Throw New CryptographicException("No key was provided for the decryption operation!")
|
|
End If
|
|
End If
|
|
If _iv.IsEmpty Then
|
|
If isEncrypting Then
|
|
_iv = RandomInitializationVector()
|
|
Else
|
|
Throw New CryptographicException("No initialization vector was provided for the decryption operation!")
|
|
End If
|
|
End If
|
|
Try
|
|
_crypto.Key = _key.Bytes
|
|
_crypto.IV = _iv.Bytes
|
|
Catch ex As CryptographicException
|
|
Throw New CryptographicException("Invalid key or initialization vector.", ex)
|
|
End Try
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Encrypts the specified Data using provided key
|
|
''' </summary>
|
|
Friend Function Encrypt(ByVal d As Data, ByVal key As Data) As Data
|
|
Me.Key = key
|
|
Return Encrypt(d)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Encrypts the specified Data using preset key and preset initialization vector
|
|
''' </summary>
|
|
Friend Function Encrypt(ByVal d As Data) As Data
|
|
Dim ms As New IO.MemoryStream
|
|
|
|
ValidateKeyAndIv(True)
|
|
|
|
Dim cs As New CryptoStream(ms, _crypto.CreateEncryptor(), CryptoStreamMode.Write)
|
|
cs.Write(d.Bytes, 0, d.Bytes.Length)
|
|
cs.Close()
|
|
ms.Close()
|
|
|
|
Return New Data(ms.ToArray)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Encrypts the stream to memory using provided key and provided initialization vector
|
|
''' </summary>
|
|
Friend Function Encrypt(ByVal s As Stream, ByVal key As Data, ByVal iv As Data) As Data
|
|
Me.IntializationVector = iv
|
|
Me.Key = key
|
|
Return Encrypt(s)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Encrypts the stream to memory using specified key
|
|
''' </summary>
|
|
Friend Function Encrypt(ByVal s As Stream, ByVal key As Data) As Data
|
|
Me.Key = key
|
|
Return Encrypt(s)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Encrypts the specified stream to memory using preset key and preset initialization vector
|
|
''' </summary>
|
|
Friend Function Encrypt(ByVal s As Stream) As Data
|
|
Dim ms As New IO.MemoryStream
|
|
Dim b(_BufferSize) As Byte
|
|
Dim i As Integer
|
|
|
|
ValidateKeyAndIv(True)
|
|
|
|
Dim cs As New CryptoStream(ms, _crypto.CreateEncryptor(), CryptoStreamMode.Write)
|
|
i = s.Read(b, 0, _BufferSize)
|
|
Do While i > 0
|
|
cs.Write(b, 0, i)
|
|
i = s.Read(b, 0, _BufferSize)
|
|
Loop
|
|
|
|
cs.Close()
|
|
ms.Close()
|
|
|
|
Return New Data(ms.ToArray)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Decrypts the specified data using provided key and preset initialization vector
|
|
''' </summary>
|
|
Friend Function Decrypt(ByVal encryptedData As Data, ByVal key As Data) As Data
|
|
Me.Key = key
|
|
Return Decrypt(encryptedData)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Decrypts the specified stream using provided key and preset initialization vector
|
|
''' </summary>
|
|
Friend Function Decrypt(ByVal encryptedStream As Stream, ByVal key As Data) As Data
|
|
Me.Key = key
|
|
Return Decrypt(encryptedStream)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Decrypts the specified stream using preset key and preset initialization vector
|
|
''' </summary>
|
|
Friend Function Decrypt(ByVal encryptedStream As Stream) As Data
|
|
Dim ms As New System.IO.MemoryStream
|
|
Dim b(_BufferSize) As Byte
|
|
|
|
ValidateKeyAndIv(False)
|
|
Dim cs As New CryptoStream(encryptedStream,
|
|
_crypto.CreateDecryptor(), CryptoStreamMode.Read)
|
|
|
|
Dim i As Integer
|
|
i = cs.Read(b, 0, _BufferSize)
|
|
|
|
Do While i > 0
|
|
ms.Write(b, 0, i)
|
|
i = cs.Read(b, 0, _BufferSize)
|
|
Loop
|
|
cs.Close()
|
|
ms.Close()
|
|
|
|
Return New Data(ms.ToArray)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Decrypts the specified data using preset key and preset initialization vector
|
|
''' </summary>
|
|
Friend Function Decrypt(ByVal encryptedData As Data) As Data
|
|
Using ms As New System.IO.MemoryStream(encryptedData.Bytes, 0, encryptedData.Bytes.Length)
|
|
ValidateKeyAndIv(False)
|
|
Using cs As New CryptoStream(ms, _crypto.CreateDecryptor(), CryptoStreamMode.Read)
|
|
Using outputMs As New MemoryStream()
|
|
Try
|
|
cs.CopyTo(outputMs)
|
|
Return New Data(outputMs.ToArray())
|
|
Catch ex As CryptographicException
|
|
Throw New CryptographicException("Unable to decrypt data. The provided key may be invalid.", ex)
|
|
End Try
|
|
End Using
|
|
End Using
|
|
End Using
|
|
End Function
|
|
|
|
End Class
|
|
|
|
#End Region
|
|
|
|
#Region " Data "
|
|
|
|
''' <summary>
|
|
''' represents Hex, Byte, Base64, or String data to encrypt/decrypt;
|
|
''' use the .Text property to set/get a string representation
|
|
''' use the .Hex property to set/get a string-based Hexadecimal representation
|
|
''' use the .Base64 to set/get a string-based Base64 representation
|
|
''' </summary>
|
|
Friend Class Data
|
|
Private _b As Byte() = Nothing
|
|
Private _MaxBytes As Integer = 0
|
|
Private _MinBytes As Integer = 0
|
|
Private _StepBytes As Integer = 0
|
|
|
|
''' <summary>
|
|
''' Determines the default text encoding across ALL Data instances
|
|
''' </summary>
|
|
Friend Shared DefaultEncoding As Text.Encoding
|
|
|
|
Shared Sub New()
|
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)
|
|
DefaultEncoding = System.Text.Encoding.GetEncoding("Windows-1252")
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Determines the default text encoding for this Data instance
|
|
''' </summary>
|
|
Friend Encoding As Text.Encoding = DefaultEncoding
|
|
|
|
''' <summary>
|
|
''' Creates new, empty encryption data
|
|
''' </summary>
|
|
Friend Sub New()
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Creates new encryption data with the specified byte array
|
|
''' </summary>
|
|
Friend Sub New(ByVal b As Byte())
|
|
_b = b
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Creates new encryption data with the specified string;
|
|
''' will be converted to byte array using default encoding
|
|
''' </summary>
|
|
Friend Sub New(ByVal s As String)
|
|
Me.Text = s
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Creates new encryption data using the specified string and the
|
|
''' specified encoding to convert the string to a byte array.
|
|
''' </summary>
|
|
Friend Sub New(ByVal s As String, ByVal encoding As System.Text.Encoding)
|
|
Me.Encoding = encoding
|
|
Me.Text = s
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' returns true if no data is present
|
|
''' </summary>
|
|
Friend ReadOnly Property IsEmpty() As Boolean
|
|
Get
|
|
If _b Is Nothing Then
|
|
Return True
|
|
End If
|
|
If _b.Length = 0 Then
|
|
Return True
|
|
End If
|
|
Return False
|
|
End Get
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' allowed step interval, in bytes, for this data; if 0, no limit
|
|
''' </summary>
|
|
Friend Property StepBytes() As Integer
|
|
Get
|
|
Return _StepBytes
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_StepBytes = Value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' allowed step interval, in bits, for this data; if 0, no limit
|
|
''' </summary>
|
|
Friend Property StepBits() As Integer
|
|
Get
|
|
Return _StepBytes * 8
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_StepBytes = Value \ 8
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' minimum number of bytes allowed for this data; if 0, no limit
|
|
''' </summary>
|
|
Friend Property MinBytes() As Integer
|
|
Get
|
|
Return _MinBytes
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_MinBytes = Value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' minimum number of bits allowed for this data; if 0, no limit
|
|
''' </summary>
|
|
Friend Property MinBits() As Integer
|
|
Get
|
|
Return _MinBytes * 8
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_MinBytes = Value \ 8
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' maximum number of bytes allowed for this data; if 0, no limit
|
|
''' </summary>
|
|
Friend Property MaxBytes() As Integer
|
|
Get
|
|
Return _MaxBytes
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_MaxBytes = Value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' maximum number of bits allowed for this data; if 0, no limit
|
|
''' </summary>
|
|
Friend Property MaxBits() As Integer
|
|
Get
|
|
Return _MaxBytes * 8
|
|
End Get
|
|
Set(ByVal Value As Integer)
|
|
_MaxBytes = Value \ 8
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Returns the byte representation of the data;
|
|
''' This will be padded to MinBytes and trimmed to MaxBytes as necessary!
|
|
''' </summary>
|
|
Friend Property Bytes() As Byte()
|
|
Get
|
|
If _MaxBytes > 0 Then
|
|
If _b.Length > _MaxBytes Then
|
|
Dim b(_MaxBytes - 1) As Byte
|
|
Array.Copy(_b, b, b.Length)
|
|
_b = b
|
|
End If
|
|
End If
|
|
If _MinBytes > 0 Then
|
|
If _b.Length < _MinBytes Then
|
|
Dim b(_MinBytes - 1) As Byte
|
|
Array.Copy(_b, b, _b.Length)
|
|
_b = b
|
|
End If
|
|
End If
|
|
Return _b
|
|
End Get
|
|
Set(ByVal Value As Byte())
|
|
_b = Value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Sets or returns text representation of bytes using the default text encoding
|
|
''' </summary>
|
|
Friend Property Text() As String
|
|
Get
|
|
If _b Is Nothing Then
|
|
Return ""
|
|
Else
|
|
'-- need to handle nulls here; oddly, C# will happily convert
|
|
'-- nulls into the string whereas VB stops converting at the
|
|
'-- first null!
|
|
Dim i As Integer = Array.IndexOf(_b, CType(0, Byte))
|
|
If i >= 0 Then
|
|
Return Me.Encoding.GetString(_b, 0, i)
|
|
Else
|
|
Return Me.Encoding.GetString(_b)
|
|
End If
|
|
End If
|
|
End Get
|
|
Set(ByVal Value As String)
|
|
_b = Me.Encoding.GetBytes(Value)
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Sets or returns Hex string representation of this data
|
|
''' </summary>
|
|
Friend Property Hex() As String
|
|
Get
|
|
Return Utils.ToHex(_b)
|
|
End Get
|
|
Set(ByVal Value As String)
|
|
_b = Utils.FromHex(Value)
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Sets or returns Base64 string representation of this data
|
|
''' </summary>
|
|
Friend Property Base64() As String
|
|
Get
|
|
Return Utils.ToBase64(_b)
|
|
End Get
|
|
Set(ByVal Value As String)
|
|
_b = Utils.FromBase64(Value)
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Returns text representation of bytes using the default text encoding
|
|
''' </summary>
|
|
Friend Shadows Function ToString() As String
|
|
Return Me.Text
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' returns Base64 string representation of this data
|
|
''' </summary>
|
|
Friend Function ToBase64() As String
|
|
Return Me.Base64
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' returns Hex string representation of this data
|
|
''' </summary>
|
|
Friend Function ToHex() As String
|
|
Return Me.Hex
|
|
End Function
|
|
|
|
End Class
|
|
|
|
#End Region
|
|
|
|
#Region " Utils "
|
|
|
|
''' <summary>
|
|
''' Friend class for shared utility methods used by multiple Encryption classes
|
|
''' </summary>
|
|
Friend Class Utils
|
|
|
|
''' <summary>
|
|
''' converts an array of bytes to a string Hex representation
|
|
''' </summary>
|
|
Friend Shared Function ToHex(ByVal ba() As Byte) As String
|
|
If ba Is Nothing OrElse ba.Length = 0 Then
|
|
Return ""
|
|
End If
|
|
Const HexFormat As String = "{0:X2}"
|
|
Dim sb As New StringBuilder
|
|
For Each b As Byte In ba
|
|
sb.Append(String.Format(HexFormat, b))
|
|
Next
|
|
Return sb.ToString
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' converts from a string Hex representation to an array of bytes
|
|
''' </summary>
|
|
Friend Shared Function FromHex(ByVal hexEncoded As String) As Byte()
|
|
If hexEncoded Is Nothing OrElse hexEncoded.Length = 0 Then
|
|
Return Nothing
|
|
End If
|
|
Try
|
|
Dim l As Integer = Convert.ToInt32(hexEncoded.Length / 2)
|
|
Dim b(l - 1) As Byte
|
|
For i As Integer = 0 To l - 1
|
|
b(i) = Convert.ToByte(hexEncoded.Substring(i * 2, 2), 16)
|
|
Next
|
|
Return b
|
|
Catch ex As Exception
|
|
Throw New System.FormatException("The provided string does not appear to be Hex encoded:" &
|
|
Environment.NewLine & hexEncoded & Environment.NewLine, ex)
|
|
End Try
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' converts from a string Base64 representation to an array of bytes
|
|
''' </summary>
|
|
Friend Shared Function FromBase64(ByVal base64Encoded As String) As Byte()
|
|
If base64Encoded Is Nothing OrElse base64Encoded.Length = 0 Then
|
|
Return Nothing
|
|
End If
|
|
Try
|
|
Return Convert.FromBase64String(base64Encoded)
|
|
Catch ex As System.FormatException
|
|
Throw New System.FormatException("The provided string does not appear to be Base64 encoded:" &
|
|
Environment.NewLine & base64Encoded & Environment.NewLine, ex)
|
|
End Try
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' converts from an array of bytes to a string Base64 representation
|
|
''' </summary>
|
|
Friend Shared Function ToBase64(ByVal b() As Byte) As String
|
|
If b Is Nothing OrElse b.Length = 0 Then
|
|
Return ""
|
|
End If
|
|
Return Convert.ToBase64String(b)
|
|
End Function
|
|
|
|
End Class
|
|
|
|
#End Region
|
|
|
|
End Namespace
|