Thread Safety RijndaelManaged, ICryptoTransform.TransformFinalBlock? - vb.net

Lets say we have this code that runs in the constructor:
Dim initVectorBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(saltValue)
Dim passPharse As String = GenerateKeyString(EncryptionKey)
Dim password As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(passPharse, saltValueBytes, passwordIterations)
Dim keyBytes As Byte() = password.GetBytes(CInt(keySize / 8))
mSymmetricKey = New RijndaelManaged()
mSymmetricKey.Padding = PaddingMode.PKCS7
mSymmetricKey.Mode = CipherMode.CBC
mSymmetricKey.BlockSize = 128
mSymmetricKey.Key = keyBytes
mSymmetricKey.IV = initVectorBytes
mDecryptor = mSymmetricKey.CreateDecryptor()
mEncryptor = mSymmetricKey.CreateEncryptor()
and then 2 public functions:
Public Function Encrypt(ByVal plainText As String) As String
Dim plainTextBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(plainText)
Dim cipherTextBytes As Byte() = mEncryptor.TransformFinalBlock(plainTextBytes, 0, plainTextBytes.Length)
Dim cipherText As String = Convert.ToBase64String(cipherTextBytes)
Return cipherText
End Function
Public Function Decrypt(ByVal cipherText As String) As String
Dim cipherTextBytes As Byte() = Convert.FromBase64String(cipherText)
Dim plainTextBytes As Byte() = mDecryptor.TransformFinalBlock(cipherTextBytes, 0, cipherTextBytes.Length)
Dim plainText As String = System.Text.Encoding.UTF8.GetString(plainTextBytes, 0, plainTextBytes.Length)
Return plainText
End Function
Would it be threadsafe to call those from more than one thread?

According to the documentation it is not thread safe. You will have RijndaelManagedTransform instances in the mDecryptor and mEncryptor variables. TransformFinalBlock is an instance method which according to MSDN is not thread safe:
Any public static (Shared in Visual
Basic) members of this type are thread
safe. Any instance members are not
guaranteed to be thread safe.
If you want to be guaranteed to have a thread safe code you might need to synchronize the call to TransformFinalBlock method.

Related

System.Security.Cryptography.CryptographicException: Bad Data

I am having this bad data problem when I tried to open it. Any idea how to solve it? When I debug it shows that CryptoStream.FlushFinalBlock() is having a problem. See codes below.
Public Class Encryption
Public Function Encrypt(ByVal plainText As String) As Byte()
Dim utf8encoder As UTF8Encoding = New UTF8Encoding()
Dim inputInBytes() As Byte = utf8encoder.GetBytes(plainText)
Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
' The ICryptTransform interface uses the TripleDES
' crypt provider along with encryption key and init vector
' information
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateEncryptor(Me.key, Me.iv)
Dim encryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
encryptedStream.Position = 0
Dim result(encryptedStream.Length - 1) As Byte
encryptedStream.Read(result, 0, encryptedStream.Length)
cryptStream.Close()
Return result
End Function
Public Function Decrypt(ByVal inputInBytes() As Byte) As String
' UTFEncoding is used to transform the decrypted Byte Array
' information back into a string.
Dim utf8encoder As UTF8Encoding = New UTF8Encoding()
Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
' As before we must provide the encryption/decryption key along with
' the init vector.
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateDecryptor(Me.key, Me.iv)
' Provide a memory stream to decrypt information into
Dim decryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
decryptedStream.Position = 0
' Read the memory stream and convert it back into a string
Dim result(decryptedStream.Length - 1) As Byte
decryptedStream.Read(result, 0, decryptedStream.Length)
cryptStream.Close()
Dim myutf As UTF8Encoding = New UTF8Encoding()
Return myutf.GetString(result)
End Function
End Class
After the cryptStream.Write you can close it and return the MemoryStream data
Public Function Encrypt(ByVal plainText As String) As Byte()
Dim utf8encoder As UTF8Encoding = New UTF8Encoding()
Dim inputInBytes() As Byte = utf8encoder.GetBytes(plainText)
Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
' The ICryptTransform interface uses the TripleDES
' crypt provider along with encryption key and init vector
' information
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateEncryptor(Me.key, Me.iv)
Dim encryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.Close()
encryptedStream.Position = 0
Return encryptedStream.ToArray()
End Function
Update: Decrypt Method
Public Function Decrypt(ByVal inputInBytes() As Byte) As String
Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
' As before we must provide the encryption/decryption key along with
' the init vector.
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateDecryptor(Me.key, Me.iv)
' Provide a memory stream to decrypt information into
Dim decryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
Return System.Text.Encoding.Unicode.GetString(decryptedStream.ToArray)
End Function
Public Function Decrypt(ByVal inputInBytes() As Byte) As String
' UTFEncoding is used to transform the decrypted Byte Array
' information back into a string.
Dim utf8encoder As UTF8Encoding = New UTF8Encoding()
Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
' As before we must provide the encryption/decryption key along with
' the init vector.
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateDecryptor(Me.key, Me.iv)
' Provide a memory stream to decrypt information into
Dim decryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
decryptedStream.Position = 0
' Read the memory stream and convert it back into a string
Dim result(decryptedStream.Length - 1) As Byte
decryptedStream.Read(result, 0, decryptedStream.Length)
cryptStream.Close()
Dim myutf As UTF8Encoding = New UTF8Encoding()
Return myutf.GetString(result)
End Function
End Class

vb.net rijndael limit to 64 character

i have problem while encrypt and decrypt using rijndael in vb.net.
it cannot work on string more than 64 character.
here is my code:
Private Function prepareRijn() As Rijndael
Dim KEY As String = Left(_KEY, 32)
Dim IV As String = Right(_KEY, 32)
Dim enc As New System.Text.UTF8Encoding
Dim byteKEY() As Byte = enc.GetBytes(KEY)
Dim byteIV() As Byte = enc.GetBytes(IV)
Dim alg As Rijndael = Rijndael.Create
alg.BlockSize = 256
alg.KeySize = 256
alg.Padding = PaddingMode.Zeros
alg.Mode = CipherMode.CBC
alg.Key = byteKEY
alg.IV = byteIV
Return alg
End Function
Function decrypt(ByVal encrypted As String) As String
encrypted = encrypted.Replace("Q2FrZQ==.", "")
Dim enc As New System.Text.UTF8Encoding
Dim alg As Rijndael = prepareRijn()
Dim ms As New MemoryStream
Dim cs As CryptoStream = New CryptoStream(ms, alg.CreateDecryptor, CryptoStreamMode.Write)
Dim data() As Byte = Convert.FromBase64String(encrypted)
cs.Write(data, 0, data.Length)
'ms.SetLength(data.Length)
Dim decrypted() As Byte
decrypted = ms.ToArray
cs.Close()
Return enc.GetString(decrypted)
End Function
Function encrypt(ByVal decrypt As String) As String
decrypt = decrypt + " "
Dim alg As Rijndael = prepareRijn()
Dim ms As New MemoryStream()
Dim cs As CryptoStream = New CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write)
Dim data() As Byte = System.Text.Encoding.UTF8.GetBytes(decrypt)
cs.Write(data, 0, data.Length)
'ms.SetLength(data.Length)
Dim encrypted() As Byte = ms.ToArray()
cs.Close()
Return Convert.ToBase64String(encrypted)
End Function
is there anything i miss during my rijndael configuration ?
I wrote complete Encryption Class for you. It works perfectly. It can be used for Both Strings and ByteArrays. This Class returns Encrypted Data in Base64, if you dont want Base64, just remove Conversion.
Imports System.Text
Imports System.Security.Cryptography
Imports System.IO
Imports System
Public Class Encryption
' Fields
Private Shared sIV As String = "Your IV Key Placed Here 32-Bytes"
Private Shared sKey As String = "Your SecKey Placed Here 32-Bytes"
' Methods
Public Shared Function DecryptRJ256(ByVal prm_text_to_decrypt As String) As String
Dim s As String = prm_text_to_decrypt
Dim managed As New RijndaelManaged With { _
.Padding = PaddingMode.Zeros, _
.Mode = CipherMode.ECB, _
.KeySize = &H100, _
.BlockSize = &H100 _
}
Dim rgbKey As Byte() = Nothing
Dim rgbIV As Byte() = Nothing
s = s.Replace("-", "+").Replace("_", "/").Replace("|", "=")
rgbKey = Encoding.ASCII.GetBytes(Encryption.sKey)
rgbIV = Encoding.ASCII.GetBytes(Encryption.sIV)
Dim transform As ICryptoTransform = managed.CreateDecryptor(rgbKey, rgbIV)
Dim buffer As Byte() = Convert.FromBase64String(s)
Dim buffer4 As Byte() = New Byte((buffer.Length + 1) - 1) {}
Dim stream As New MemoryStream(buffer)
Dim stream2 As New CryptoStream(stream, transform, CryptoStreamMode.Read)
stream2.Read(buffer4, 0, buffer4.Length)
Return Encoding.ASCII.GetString(buffer4)
End Function
Public Shared Function EncryptRJ256(ByVal prm_text_to_encrypt As String) As String
Dim s As String = prm_text_to_encrypt
Dim managed As New RijndaelManaged With { _
.Padding = PaddingMode.Zeros, _
.Mode = CipherMode.ECB, _
.KeySize = &H100, _
.BlockSize = &H100 _
}
Dim buffer As Byte() = Nothing
Dim rgbKey As Byte() = Nothing
Dim rgbIV As Byte() = Nothing
rgbKey = Encoding.ASCII.GetBytes(Encryption.sKey)
rgbIV = Encoding.ASCII.GetBytes(Encryption.sIV)
Dim transform As ICryptoTransform = managed.CreateEncryptor(rgbKey, rgbIV)
Dim stream As New MemoryStream
Dim stream2 As New CryptoStream(stream, transform, CryptoStreamMode.Write)
buffer = Encoding.ASCII.GetBytes(s)
stream2.Write(buffer, 0, buffer.Length)
stream2.FlushFinalBlock()
Return Convert.ToBase64String(stream.ToArray).Replace("+", "-").Replace("/", "_").Replace("=", "|")
End Function
Public Shared Function EncryptRJ256(ByVal ArrayByte As Byte()) As String
Dim managed As New RijndaelManaged With { _
.Padding = PaddingMode.Zeros, _
.Mode = CipherMode.ECB, _
.KeySize = &H100, _
.BlockSize = &H100 _
}
Dim rgbKey As Byte() = Nothing
Dim rgbIV As Byte() = Nothing
rgbKey = Encoding.ASCII.GetBytes(Encryption.sKey)
rgbIV = Encoding.ASCII.GetBytes(Encryption.sIV)
Dim transform As ICryptoTransform = managed.CreateEncryptor(rgbKey, rgbIV)
Dim stream As New MemoryStream
Dim stream2 As New CryptoStream(stream, transform, CryptoStreamMode.Write)
stream2.Write(ArrayByte, 0, ArrayByte.Length)
stream2.FlushFinalBlock()
Return Convert.ToBase64String(stream.ToArray).Replace("+", "-").Replace("/", "_").Replace("=", "|")
End Function
Public Shared Function getMD5Hash(ByVal input As String) As String
Dim md As MD5 = MD5.Create
Dim bytes As Byte() = Encoding.ASCII.GetBytes(input)
Dim buffer2 As Byte() = md.ComputeHash(bytes)
Dim builder As New StringBuilder
Dim i As Integer
For i = 0 To buffer2.Length - 1
builder.Append(buffer2(i).ToString("X2"))
Next i
Return builder.ToString
End Function
Public Shared Function FromBase64String(ByVal prm_text_to_decrypt As String) As String
Dim s As String = prm_text_to_decrypt
s = s.Replace("-", "+").Replace("_", "/").Replace("|", "=")
Dim buffer As Byte() = Convert.FromBase64String(s)
Return Encoding.ASCII.GetString(buffer)
End Function
End Class

Shorten a string containing data

I am creating an application to create a key that is unique to each computer. This info is derived from the OS serial number and processorID.
Is there a way to 'shorten' a string? Maybe by converting it to HEX or something else...
The reason is this: I used to use a VB6 section of code (http://www.planet-source-code.com/vb...48926&lngWId=1) that gets the details and the output is only 13 digits long. Mine is a lot longer, but gets the same info...
BTW, the link I posted above won multiple awards, but I am having huge trouble in converting it to .NET. Has anyone by any chance converted it, or know of someone who has? Or a tool that actually works?
Thanks
EDIT
Here is the full working link: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=48926&lngWId=1
It sounds like you want a 'hashing algorithm' or 'hash function'. They are a common concept: http://en.wikipedia.org/wiki/Hash_function
Generally speaking you can simply write your own function to take a string and return a hashed number but there is some suitable code here that uses the .NET framework: http://support.microsoft.com/kb/301053
Here is a working example which retrieves the Processor ID, for the first Processor found, and the OS Serial Number; it concatenates these to strings together and then performs various encodings on them.
This is a simple VB.Net Console project. Be sure to reference the System.Management assembly in your project. Just copy and paste this code example into the main module, set a breakpoint at the end of Sub Main(), and look at the various results.
Module Module1
Sub Main()
Dim uniqueID As String = GetUniqueID()
' convert it to a base64 string
Dim encoding As New Text.ASCIIEncoding()
Dim result1 = Convert.ToBase64String(encoding.GetBytes(uniqueID))
' compress it
Dim result2 As String = CompressString(uniqueID)
Dim result3 As String = DecompressString(result2)
' encrypt it
Dim result4 As String = AES_Encrypt(uniqueID, "password")
Dim result5 As String = AES_Decrypt(result4, "password")
' hash it
Dim result6 As String = HashString(uniqueID)
End Sub
Private Function GetUniqueID() As String
Dim result As String = GetOSSerialNumber()
Dim processorIDs() As String = GetProcessorIDs()
If ((processorIDs IsNot Nothing) AndAlso (processorIDs.Count > 0)) Then
result &= processorIDs(0)
End If
Return result
End Function
Private Function GetProcessorIDs() As String()
Dim result As New List(Of String)
Dim searcher = New System.Management.ManagementObjectSearcher("Select ProcessorId from Win32_Processor")
For Each managementObj In searcher.Get()
result.Add(CStr(managementObj.Properties("ProcessorId").Value))
Next
Return result.ToArray()
End Function
Private Function GetOSSerialNumber() As String
Dim result As String = ""
Dim searcher = New System.Management.ManagementObjectSearcher("Select SerialNumber from Win32_OperatingSystem")
For Each managementObj In searcher.Get()
result = CStr(managementObj.Properties("SerialNumber").Value)
Next
Return result
End Function
Public Function CompressString(ByVal source As String) As String
Dim result As String = ""
Dim encoding As New Text.ASCIIEncoding()
Dim bytes() As Byte = encoding.GetBytes(source)
Using ms As New IO.MemoryStream
Using gzsw As New System.IO.Compression.GZipStream(ms, IO.Compression.CompressionMode.Compress)
gzsw.Write(bytes, 0, bytes.Length)
gzsw.Close()
result = Convert.ToBase64String(ms.ToArray)
End Using
End Using
Return result
End Function
Public Function DecompressString(ByVal source As String) As String
Dim result As String = ""
Dim bytes() As Byte = Convert.FromBase64String(source)
Using ms As New IO.MemoryStream(bytes)
Using gzsw As New System.IO.Compression.GZipStream(ms, IO.Compression.CompressionMode.Decompress)
Dim data(CInt(ms.Length)) As Byte
gzsw.Read(data, 0, CInt(ms.Length))
Dim encoding As New Text.ASCIIEncoding()
result = encoding.GetString(data)
End Using
End Using
Return result
End Function
Public Function AES_Encrypt(ByVal input As String, ByVal pass As String) As String
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim encrypted As String = ""
Try
Dim hash(31) As Byte
Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
Array.Copy(temp, 0, hash, 0, 16)
Array.Copy(temp, 0, hash, 15, 16)
AES.Key = hash
AES.Mode = Security.Cryptography.CipherMode.ECB
Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(input)
encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Catch ex As Exception
End Try
Return encrypted
End Function
Public Function AES_Decrypt(ByVal input As String, ByVal pass As String) As String
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim decrypted As String = ""
Try
Dim hash(31) As Byte
Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
Array.Copy(temp, 0, hash, 0, 16)
Array.Copy(temp, 0, hash, 15, 16)
AES.Key = hash
AES.Mode = Security.Cryptography.CipherMode.ECB
Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
Dim Buffer As Byte() = Convert.FromBase64String(input)
decrypted = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Catch ex As Exception
End Try
Return decrypted
End Function
Private Function HashString(ByVal source As String) As String
Dim encoding As New Text.ASCIIEncoding()
Dim bytes() As Byte = encoding.GetBytes(source)
Dim workingHash() As Byte = New System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(bytes)
Dim result As String = ""
For Each b In workingHash
result = result & b.ToString("X2")
Next
Return result
End Function
End Module

AES encryption/decryption

Here is some code that works well for strings:
Public Function AESEncrypt(ByVal PlainText As String, ByVal Password As String, ByVal salt As String)
Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5
Dim PasswordIterations As String = 2
Dim InitialVector As String = "CanEncryption123" 'This should be a string of 16 ASCII characters.
Dim KeySize As Integer = 256 'Can be 128, 192, or 256.
If (String.IsNullOrEmpty(PlainText)) Then
Return ""
Exit Function
End If
Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
Dim PlainTextBytes As Byte() = Encoding.UTF8.GetBytes(PlainText)
Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations)
Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
SymmetricKey.Mode = CipherMode.CBC
Dim CipherTextBytes As Byte() = Nothing
Using Encryptor As ICryptoTransform = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes)
Using MemStream As New MemoryStream()
Using CryptoStream As New CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)
CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length)
CryptoStream.FlushFinalBlock()
CipherTextBytes = MemStream.ToArray()
MemStream.Close()
CryptoStream.Close()
End Using
End Using
End Using
SymmetricKey.Clear()
Return Convert.ToBase64String(CipherTextBytes)
End Function
Public Function AESDecrypt(ByVal CipherText As String, ByVal password As String, ByVal salt As String) As String
Dim HashAlgorithm As String = "SHA1"
Dim PasswordIterations As String = 2
Dim InitialVector As String = "CanEncryption123"
Dim KeySize As Integer = 256
If (String.IsNullOrEmpty(CipherText)) Then
Return ""
End If
Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
Dim CipherTextBytes As Byte() = Convert.FromBase64String(CipherText)
Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(password, SaltValueBytes, HashAlgorithm, PasswordIterations)
Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
SymmetricKey.Mode = CipherMode.CBC
Dim PlainTextBytes As Byte() = New Byte(CipherTextBytes.Length - 1) {}
Dim ByteCount As Integer = 0
Using Decryptor As ICryptoTransform = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes)
Using MemStream As MemoryStream = New MemoryStream(CipherTextBytes)
Using CryptoStream As CryptoStream = New CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)
ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length)
MemStream.Close()
CryptoStream.Close()
End Using
End Using
End Using
SymmetricKey.Clear()
Return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount)
End Function
Can I have some help in modifying these functions to encrypt/decrypt byte arrays rather than strings. Also, to have the functions return the encrypted/decrypted byte array, rather than a string.
thanks
I am using this (found on Google) for strings AES Encryption/Decryption:
Imports System.Security.Cryptography
Namespace TextCrypters
Public Class AESCrypter
Public Shared pass As String = "password"
Public Shared Function AES_Encrypt(ByVal input As String) As String
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim encrypted As String = ""
Try
Dim hash(31) As Byte
Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
Array.Copy(temp, 0, hash, 0, 16)
Array.Copy(temp, 0, hash, 15, 16)
AES.Key = hash
AES.Mode = CipherMode.ECB
Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(input)
encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Return encrypted
Catch ex As Exception
Return Nothing
End Try
End Function
Public Shared Function AES_Decrypt(ByVal input As String) As String
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim decrypted As String = ""
Try
Dim hash(31) As Byte
Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
Array.Copy(temp, 0, hash, 0, 16)
Array.Copy(temp, 0, hash, 15, 16)
AES.Key = hash
AES.Mode = CipherMode.ECB
Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
Dim Buffer As Byte() = Convert.FromBase64String(input)
decrypted = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Return decrypted
Catch ex As Exception
Return Nothing
End Try
End Function
End Class
End Namespace
To use it just do this:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox2.Text = AESCrypter.AES_Encrypt(TextBox1.Text)
End Sub
Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TextBox4.Text = AESCrypter.AES_Decrypt(TextBox3.Text)
End Sub
Just copy everything in a new function starting from Dim ByteCount As Integer = 0 to SymmetricKey.Clear() to get rid of all strings? After that you only need to define the arguments to the function.
The simplest way is to use a wrapper function that just converts the byte array to a string, encrypts it with your AESEncrypt function, and converts the string back to a byte array. You can find conversion functions for VB.net here.
Edited to add: I think I got this wrong. It seems that a VB String is in Unicode format, and these translation functions convert it to/from a UTF8 byte array. Which is not what was required...
Public Function AESEncrypt(ByVal PlainBytes As Byte, ByVal Password As String, ByVal salt As String)
Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5
Dim PasswordIterations As String = 2
Dim InitialVector As String = "CanEncryption123" 'This should be a string of 16 ASCII characters.
Dim KeySize As Integer = 256 'Can be 128, 192, or 256.
Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations)
Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
SymmetricKey.Mode = CipherMode.CBC
Dim CipherTextBytes As Byte() = Nothing
Using Encryptor As ICryptoTransform = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes)
Using MemStream As New MemoryStream()
Using CryptoStream As New CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)
CryptoStream.Write(PlainBytes, 0, PlainBytes.Length)
CryptoStream.FlushFinalBlock()
CipherTextBytes = MemStream.ToArray()
MemStream.Close()
CryptoStream.Close()
End Using
End Using
End Using
SymmetricKey.Clear()
Return Convert.ToBase64String(CipherTextBytes)
End Function
Public Function AESDecrypt(ByVal CipherBytes As Byte, ByVal password As String, ByVal salt As String) As String
Dim HashAlgorithm As String = "SHA1"
Dim PasswordIterations As String = 2
Dim InitialVector As String = "CanEncryption123"
Dim KeySize As Integer = 256
If (String.IsNullOrEmpty(CipherText)) Then
Return ""
End If
Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(password, SaltValueBytes, HashAlgorithm, PasswordIterations)
Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
SymmetricKey.Mode = CipherMode.CBC
Dim PlainTextBytes As Byte() = New Byte(CipherBytes.Length - 1) {}
Dim ByteCount As Integer = 0
Using Decryptor As ICryptoTransform = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes)
Using MemStream As MemoryStream = New MemoryStream(CipherBytes)
Using CryptoStream As CryptoStream = New CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)
ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length)
MemStream.Close()
CryptoStream.Close()
End Using
End Using
End Using
SymmetricKey.Clear()
Return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount)
End Function
The code you are using actually converts the input string to byte array. This code accepts byte array.

Error on encryption/decryption files

When I decrypt an encrypted file; it doesn't have the same size in bytes as the original file and the the hash of the file is different.
I get the bytes of the file using File.ReadAllBytes and send to EncryptBytes with the password. Also the same with DecryptBytes.
When I receive the bytes encrypted or decrypted i save them using File.WriteAllBytes.
I need that the decrypted file and original file have the same hash an bytes.
Please help
This my code:
Public Function EncryptBytes(ByVal pass As String, ByVal bytes() As Byte)
Dim myRijndael As New RijndaelManaged
myRijndael.Padding = PaddingMode.Zeros
myRijndael.KeySize = 256
myRijndael.BlockSize = 256
Dim encrypted() As Byte
Dim key() As Byte = CreateKey(pass)
Dim IV() As Byte = CreateIV(pass)
Dim encryptor As ICryptoTransform = myRijndael.CreateEncryptor(key, IV)
Dim msEncrypt As New MemoryStream()
Dim csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
csEncrypt.Write(bytes, 0, bytes.Length)
csEncrypt.FlushFinalBlock()
encrypted = msEncrypt.ToArray()
Return encrypted
End Function
Public Function DecryptBytes(ByVal pass As String, ByVal bytes() As Byte)
Dim myRijndael As New RijndaelManaged
myRijndael.Padding = PaddingMode.Zeros
myRijndael.KeySize = 256
myRijndael.BlockSize = 256
Dim key() As Byte = CreateKey(pass)
Dim IV() As Byte = CreateIV(pass)
Dim decryptor As ICryptoTransform = myRijndael.CreateDecryptor(key, IV)
Dim fromEncrypt() As Byte = New Byte(bytes.Length) {}
Dim msDecrypt As New MemoryStream(bytes)
Dim csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length)
Return fromEncrypt
End Function
Private Function CreateKey(ByVal strPassword As String) As Byte()
Dim chrData() As Char = strPassword.ToCharArray
Dim intLength As Integer = chrData.GetUpperBound(0)
Dim bytDataToHash(intLength) As Byte
For i As Integer = 0 To chrData.GetUpperBound(0)
bytDataToHash(i) = CByte(Asc(chrData(i)))
Next
Dim SHA512 As New System.Security.Cryptography.SHA512Managed
Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
Dim bytKey(31) As Byte
For i As Integer = 0 To 31
bytKey(i) = bytResult(i)
Next
Return bytKey
End Function
Private Function CreateIV(ByVal strPassword As String) As Byte()
Dim chrData() As Char = strPassword.ToCharArray
Dim intLength As Integer = chrData.GetUpperBound(0)
Dim bytDataToHash(intLength) As Byte
For i As Integer = 0 To chrData.GetUpperBound(0)
bytDataToHash(i) = CByte(Asc(chrData(i)))
Next
Dim SHA512 As New System.Security.Cryptography.SHA512Managed
Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
Dim bytIV(31) As Byte
For i As Integer = 32 To 47
bytIV(i - 32) = bytResult(i)
Next
Return bytIV
End Function
Your DecryptBytes() method is broken. You are not using the return value of csDecrypt.Read(), it tells you have many bytes were decrypted. That will not be the same as fromEncrypt.Length. You'd also have a very hard time guessing how large a byte array to pass to this function.
Consider changing the function to return a MemoryStream. Call Read() in a loop and write what was read to the memory stream. Exit the loop when Read() returns 0.
Try this:
Public Function EncryptBytes(ByVal pass As String, ByVal bytes() As Byte)
Dim myRijndael As New RijndaelManaged
myRijndael.Padding = PaddingMode.PKCS7
myRijndael.Mode = CipherMode.CBC
myRijndael.KeySize = 256
myRijndael.BlockSize = 256
Dim encrypted() As Byte
Dim key() As Byte = CreateKey(pass)
Dim IV() As Byte = CreateIV(pass)
Dim encryptor As ICryptoTransform = myRijndael.CreateEncryptor(key, IV)
Dim msEncrypt As New MemoryStream()
Dim csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
csEncrypt.Write(bytes, 0, bytes.Length)
csEncrypt.FlushFinalBlock()
encrypted = msEncrypt.ToArray()
Return encrypted
msEncrypt.Close()
csEncrypt.Close()
End Function
Public Function DecryptBytes(ByVal pass As String, ByVal bytes() As Byte)
Dim myRijndael As New RijndaelManaged
myRijndael.Padding = PaddingMode.PKCS7
myRijndael.Mode = CipherMode.CBC
myRijndael.KeySize = 256
myRijndael.BlockSize = 256
Dim decrypted() As Byte
Dim key() As Byte = CreateKey(pass)
Dim IV() As Byte = CreateIV(pass)
Dim decryptor As ICryptoTransform = myRijndael.CreateDecryptor(key, IV)
Dim msDecrypt As New MemoryStream()
Dim csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write)
csDecrypt.Write(bytes, 0, bytes.Length)
csDecrypt.FlushFinalBlock()
decrypted = msDecrypt.ToArray()
Return decrypted
msDecrypt.Close()
csDecrypt.Close()
End Function