System.Security.Cryptography.CryptographicException: Bad Data - vb.net

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

Related

Serialization Cryptography Error

I am having trouble using encryption with serialization when deserializing an object.
This is the error:
Failed to deserialize. Reason: End of Stream encountered before parsing was completed
Here is my code:
Imports System.IO
Imports System.Security.Cryptography
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Text
Module TestModEncryption
Public Sub SaveEncryptedObjectToFile(FileName As String, Item As Object)
Dim fs As FileStream
Dim encryptor As CryptoStream
Dim formatter As New BinaryFormatter
Dim password As String = "MyPassword"
Dim salt As String = "InitialVector123"
Dim AES As AesManaged = New AesManaged
AES.Padding = PaddingMode.None
AES.Mode = CipherMode.CBC
Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5
Dim PasswordIterations As Integer = 2
Dim InitialVector As String = "InitialVector123" '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 New Rfc2898DeriveBytes(password, SaltValueBytes, PasswordIterations)
Dim KeyBytes As Byte() = DerivedPassword.GetBytes(CInt(KeySize / 8))
Dim encryptTransf As ICryptoTransform = AES.CreateEncryptor(KeyBytes, InitialVectorBytes)
fs = New FileStream(FileName, FileMode.Create)
encryptor = New CryptoStream(fs, encryptTransf, CryptoStreamMode.Write)
Try
formatter.Serialize(encryptor, Item)
Catch e As SerializationException
Console.WriteLine("Failed to serialize. Reason: " & e.Message)
Throw
Finally
fs.Close()
End Try
End Sub
Public Function OpenEncryptedObjectFromFile(FileName As String) As Object
Dim fs As New FileStream(FileName, FileMode.Open)
Dim decryptor As CryptoStream
Dim ItemToReturn As New Object
Dim password As String = "MyPassword"
Dim salt As String = "InitialVector123"
Dim AES As AesManaged = New AesManaged
AES.Padding = PaddingMode.None
AES.Mode = CipherMode.CBC
Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5
Dim PasswordIterations As Integer = 2
Dim InitialVector As String = "InitialVector123" '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 New Rfc2898DeriveBytes(password, SaltValueBytes, PasswordIterations)
Dim KeyBytes As Byte() = DerivedPassword.GetBytes(CInt(KeySize / 8))
Dim decryptTrans As ICryptoTransform = AES.CreateDecryptor(KeyBytes, InitialVectorBytes)
Try
Dim formatter As New BinaryFormatter
decryptor = New CryptoStream(fs, decryptTrans, CryptoStreamMode.Read)
ItemToReturn = DirectCast(formatter.Deserialize(decryptor), Object)
Return ItemToReturn
Catch e As SerializationException
MsgBox("Failed to deserialize. Reason: " & e.Message)
Return Nothing
'Throw
Finally
fs.Close()
End Try
End Function
End Module
Crypto is somewhat complex. First get the crypto working, just the crypto. Start with a piece of text: "I wandered lonely as an armadillo." Use your code to encrypt and decrypt that text, forgetting about the serialization. When that is working correctly then, and only then, use your working crypto code to encrypt/decrypt the serialized object.
Have you successfully serialized/deserialized your object without any encryption?
On a brief glance, you need to set padding to PKCS#7 (aka PKCS#5). Your PaddingMode.None may be what is causing the problem. Without padding your final block may not be being processed correctly. Obviously you need to use the same padding for both encryption and decryption.

Overflow error for encryption

I am getting an overflow error in the following code:
Public Shared Function AESFileEncrypt(inputFilename As String, outputFilename As String) As Boolean
'Create SymmetricAlgorithm object and specify the Key and IV.
Dim AES As RijndaelManaged = New RijndaelManaged
AES.Key = objKeys.aesKey
AES.IV = objKeys.aesIV
'Create an ICryptoTransform (Encryptor) object.
Dim Encryptor As ICryptoTransform
Encryptor = AES.CreateEncryptor
'Read the unencrypted file.
Dim InputFileStream As FileStream
InputFileStream = New FileStream(inputFilename, FileMode.Open, FileAccess.Read)
Dim InputFileData(CType(InputFileStream.Length, Integer)) As Byte
InputFileStream.Read(InputFileData, 0, CType(InputFileStream.Length, Integer))
Dim OutputFileStream As FileStream
OutputFileStream = New FileStream(outputFilename, FileMode.Create, FileAccess.Write)
'Create a CryptoStream object using the Stream and ICryptoTransform objects.
Dim EncryptCryptoStream As CryptoStream
EncryptCryptoStream = New CryptoStream(OutputFileStream, Encryptor, CryptoStreamMode.Write)
EncryptCryptoStream.Write(InputFileData, 0, InputFileData.Length)
EncryptCryptoStream.FlushFinalBlock()
'Clear any sensitive data from the cyptographic object.
AES.Clear()
'Close stream objects.
EncryptCryptoStream.Close()
InputFileStream.Close()
OutputFileStream.Close()
Return True
'Catch ex As Exception
'Debug.Print("AESFileEncrypt", ex.Message)
'Return False
'End Try
End Function
The error is at this line:
Dim InputFileData(CType(InputFileStream.Length, Integer)) As Byte
This happens on large files. I know it is because the byte array cannot be that large. Can I please have some help to modify this code to get it working?
Thanks
EDIT
This is my current work on this function:
Public Function AESFileEncrypt(inputFilename As String, outputFilename As String, Password As String, Salt As String) As Boolean
Dim AES As RijndaelManaged = New RijndaelManaged
Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5
Dim PasswordIterations As String = 2
Dim InitialVector As String = "WinStorePassword" '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 Encryptor As ICryptoTransform
Encryptor = AES.CreateEncryptor(KeyBytes, InitialVectorBytes)
Dim InputFileStream As FileStream
InputFileStream = New FileStream(inputFilename, FileMode.Open, FileAccess.Read)
Dim OutputFileStream As FileStream
OutputFileStream = New FileStream(outputFilename, FileMode.Create, FileAccess.Write)
Dim EncryptCryptoStream As CryptoStream
EncryptCryptoStream = New CryptoStream(OutputFileStream, Encryptor, CryptoStreamMode.Write)
Const BUFFER_SIZE As Integer = 4096
Dim buffer(BUFFER_SIZE - 1) As Byte
Dim Position As Long
Do
If (Position + BUFFER_SIZE) > InputFileStream.Length Then
InputFileStream.Read(buffer, Position, InputFileStream.Length - Position)
EncryptCryptoStream.Write(buffer, Position, BUFFER_SIZE)
Exit Do
Else
InputFileStream.Read(buffer, Position, BUFFER_SIZE)
EncryptCryptoStream.Write(buffer, Position, BUFFER_SIZE)
End If
Position += BUFFER_SIZE
Loop
EncryptCryptoStream.FlushFinalBlock()
AES.Clear()
EncryptCryptoStream.Close()
InputFileStream.Close()
OutputFileStream.Close()
Return True
End Function
Is this correct? I did a test an a small file, and the output was a lot larger than i expected?

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.

How to make Rijndael CBC mode work in vb.net

I'm trying to make rijndael work in CBC mode. I'm not exactly sure how should I do it. I think problem in my current code is that the stream is initialized every time in the beginning of encryption, so no avalanche effect occurs (same data is encrypted twice and the output of those two encryption is the same which it should not be).
I tried to initialize the cryptostream only once but then my coded crashed because the canwrite property of cryptostream goes to false after the first write to the cryptostream.
Here is the code what I have now:
Sub Main()
Dim rij As New RijndaelManaged
Dim iv(15) As Byte
Dim key(15) As Byte
Dim secret() As Byte = {59, 60, 61}
Dim cs As ICryptoTransform
Dim cstream As CryptoStream
Dim out() As Byte
Dim NewRandom As New RNGCryptoServiceProvider()
NewRandom.GetBytes(iv)
NewRandom.GetBytes(key)
rij = New RijndaelManaged()
rij.KeySize = 128
rij.Padding = PaddingMode.PKCS7
rij.Mode = CipherMode.CBC
rij.IV = iv
rij.Key = key
cs = rij.CreateEncryptor()
Dim ms_in As New MemoryStream
cstream = New CryptoStream(ms_in, cs, CryptoStreamMode.Write)
Using cstream
cstream.Write(secret, 0, 3)
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length))
Erase out
ms_in = New MemoryStream
cstream = New CryptoStream(ms_in, cs, CryptoStreamMode.Write)
Using cstream
cstream.Write(secret, 0, 3)
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length))
End Sub
and the conversion function to convert an array to string
Public Function ArrayToString(ByVal bytes() As Byte, ByVal length As Integer) As String
If bytes.Length = 0 Then Return String.Empty
Dim sb As New System.Text.StringBuilder(length)
Dim k As Integer = length - 1
Dim i As Integer
For i = 0 To k
sb.Append(Chr(bytes(i)))
Next
Return sb.ToString()
End Function
This is what I need:
cs = rij.CreateEncryptor()
Dim ms_in As New MemoryStream
cstream = New CryptoStream(ms_in, cs, CryptoStreamMode.Write)
Using cstream
cstream.Write(secret, 0, 3) 'encrypt
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length)) 'see the encrypted message
Erase out
Using cstream
cstream.Write(secret, 0, 3) 'encrypt, this will crash here and this is the problem I'm trying to solve
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length)) 'see the encrypted message this should not be the same as the first one
Try this:
Public Sub Run()
Dim key() As Byte = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
Dim plaintext1 As Byte() = {59, 60, 61}
Dim plaintext2 As Byte() = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, _
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, _
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, _
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 _
}
Roundtrip(plaintext1, key)
System.Console.WriteLine()
Roundtrip(plaintext2, key)
End Sub
Public Sub Roundtrip(ByRef plaintext As Byte(), ByRef key As Byte())
Dim rij As New RijndaelManaged
Dim iv(15) As Byte
Dim encryptor As ICryptoTransform
Dim decryptor As ICryptoTransform
Dim out() As Byte
'Dim NewRandom As New RNGCryptoServiceProvider()
'NewRandom.GetBytes(iv)
'NewRandom.GetBytes(key)
Console.WriteLine("Original:")
Console.WriteLine(ArrayToString(plaintext))
System.Console.WriteLine()
rij = New RijndaelManaged()
rij.KeySize = key.Length * 8 ' 16 byte key == 128 bits
rij.Padding = PaddingMode.PKCS7
rij.Mode = CipherMode.CBC
rij.IV = iv
rij.Key = key
encryptor = rij.CreateEncryptor()
Using msIn = New MemoryStream
Using cstream = New CryptoStream(msIn, encryptor, CryptoStreamMode.Write)
cstream.Write(plaintext, 0, plaintext.Length)
End Using
out = msIn.ToArray
Console.WriteLine("Encrypted:")
Console.WriteLine("{0}", ArrayToString(out))
System.Console.WriteLine()
End Using
decryptor = rij.CreateDecryptor()
Using msIn = New MemoryStream
Using cstream = New CryptoStream(msIn, decryptor, CryptoStreamMode.Write)
cstream.Write(out, 0, out.Length)
End Using
out = msIn.ToArray
Console.WriteLine("Decrypted: ")
Console.WriteLine("{0}", ArrayToString(out))
System.Console.WriteLine()
End Using
End Sub
Public Shared Function ArrayToString(ByVal bytes As Byte()) As String
Dim sb As New System.Text.StringBuilder()
Dim i As Integer
For i = 0 To bytes.Length-1
if (i <> 0 AND i mod 16 = 0) Then
sb.Append(Environment.NewLine)
End If
sb.Append(System.String.Format("{0:X2} ", bytes(i)))
Next
Return sb.ToString().Trim()
End Function
I made these basic changes to get it to work:
create a Decryptor
properly manage buffers and streams (see the Using clauses I added)
I also re-organized a little, and modified your code slightly to use a constant IV (all zeros) and use a constant key. This is so that you can get repeatable results from one run to the next. In a real app you would use a randomized IV and use a password-derived key. (See Rfc2898DeriveBytes)
ok, that allows the code to compile. I think you want to see the effect of chaining. That is not so easy, but maybe something like this will show you what you want to see:
For i As Integer = 1 To 2
Using ms = New MemoryStream
Using cstream = New CryptoStream(ms, encryptor, CryptoStreamMode.Write)
For j As Integer = 1 To i
cstream.Write(plaintext, 0, plaintext.Length)
Next j
End Using
out = ms.ToArray
Console.WriteLine("Encrypted (cycle {0}):", i)
Console.WriteLine("{0}", ArrayToString(out))
System.Console.WriteLine()
End Using
Next i

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