Decrypt the contents of a folder - VB.NET - vb.net

I've been tasked with making an encryption program and part of the task is to Encrypt/Decrypt a folder.
The encryption works exactly how I want but when I try to decrypt it gives me an error:
"Length of the data to decrypt is invalid".
All I can say I've really changed is that I'm using DES.CreateDecryptor instead of the DES.CreateEncryptor in my encryption code. Though it looks like there's more to it than that for it to work.
Just wondering how I fix this really. I'll leave the relevant portion of my code below.
Dim folderinfo As New DirectoryInfo(folderpath)
For Each File In Directory.GetFiles(folderinfo.FullName)
Dim outputFile As String
outputFile = File
Dim fsInput As New FileStream(File, FileMode.Open, FileAccess.Read)
Dim bytearrayinput(fsInput.Length) As Byte
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)
fsInput.Close()
Dim skey As String
skey = Encrypt
Dim fsDecrypted As New FileStream(File, FileMode.Create, FileAccess.Write)
Dim DES As New DESCryptoServiceProvider
DES.Key = ASCIIEncoding.ASCII.GetBytes(skey)
DES.IV = ASCIIEncoding.ASCII.GetBytes(skey)
Dim desdecrypt As ICryptoTransform
desdecrypt = DES.CreateDecryptor()
Dim cryptostream As New CryptoStream(fsDecrypted, desdecrypt, CryptoStreamMode.Write)
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)
cryptostream.Close()
fsDecrypted.Close()
txtDecrypt.Text = "All files decrypted"

You've done a classic mistake when instantiating the array. An array should be instantiated with the size (n - 1) where n is the number of elements. To set the right size, all you have to do is to subtract 1 from the fsInput length.
Dim bytearrayinput(fsInput.Length - 1) As Byte

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

How do I reload the formatted text into RTB?

I have a RTB in VB.NET, and put an event handler to save the formatted text into a file after encrypting it. However, I can't figure out how to reload the formatting - when I open it, it shows the symbols of formatting instead of formatted text. Here's my code:
Dim FileName As String = TextBox1.Text
File.Delete(FileName)
Dim EncryptElement As New TripleDESCryptoServiceProvider
EncryptElement.Key = {AscW("B"c), AscW("A"c), AscW("1"c), AscW("R"c), AscW("3"c), AscW("9"c), AscW("G"c), AscW("V"c), AscW("5"c), AscW("S"c), AscW("P"c), AscW("0"c), AscW("L"c), AscW("Z"c), AscW("4"c), AscW("M"c)} '128 bit Key
EncryptElement.IV = {AscW("N"c), AscW("B"c), AscW("5"c), AscW("3"c), AscW("G"c), AscW("L"c), AscW("2"c), AscW("Q"c)} ' 64 bit Initialization Vector
Dim fStream As FileStream = File.Open(FileName, FileMode.OpenOrCreate)
Dim cStream As New CryptoStream(fStream, New TripleDESCryptoServiceProvider().CreateEncryptor(EncryptElement.Key, EncryptElement.IV), CryptoStreamMode.Write)
Dim sWriter As New StreamWriter(cStream)
sWriter.WriteLine(RichTextBox1.Rtf)
sWriter.Close()
cStream.Close()
fStream.Close()
The above code is for saving, and the below code is for opening.
Dim FileName As String = TextBox1.Text
Dim DecryptElement As New TripleDESCryptoServiceProvider
DecryptElement.Key = {AscW("B"c), AscW("A"c), AscW("1"c), AscW("R"c), AscW("3"c), AscW("9"c), AscW("G"c), AscW("V"c), AscW("5"c), AscW("S"c), AscW("P"c), AscW("0"c), AscW("L"c), AscW("Z"c), AscW("4"c), AscW("M"c)}
DecryptElement.IV = {AscW("N"c), AscW("B"c), AscW("5"c), AscW("3"c), AscW("G"c), AscW("L"c), AscW("2"c), AscW("Q"c)}
Dim fStream As FileStream = File.Open(FileName, FileMode.OpenOrCreate)
Dim cStream As New CryptoStream(fStream, New TripleDESCryptoServiceProvider().CreateDecryptor(DecryptElement.Key, DecryptElement.IV), CryptoStreamMode.Read)
Dim sReader As New StreamReader(cStream)
Dim DecryptedData As String = ""
DecryptedData = sReader.ReadToEnd
RichTextBox1.AppendText(DecryptedData)
RichTextBox1.Enabled = True
Button1.Text = "OK"
sReader.Close()
cStream.Close()
fStream.Close()
Where is the problem?
You need RichTextBox1.SaveFile(SomeStream, RichTextBoxStreamType) I think StreamWriter is stuffing it up.
Oh and seeing as you just gave the world the keys for your encryption you might want to come up with a new one...
Added after comment not proven though.
Replace these two lines in your save routine
Dim sWriter As New StreamWriter(cStream)
sWriter.WriteLine(RichTextBox1.Rtf)
with
RichTextBox1.SaveFile(cStream,RichTextBoxStreamType.RichText);
and get rid of swriter.Close()
I think.

The process cannot access the file[VB.Net]

I'm trying to save a file, then crypt is and delete the temporary uncrypted file. This is my encryption sub, the error line occurs on the last line.
Sub EncryptFile(ByVal sInputFilename As String, _
ByVal sOutputFilename As String, _
ByVal sKey As String)
Dim fsInput As New FileStream(sInputFilename, _
FileMode.Open, FileAccess.Read)
Dim fsEncrypted As New FileStream(sOutputFilename, _
FileMode.Create, FileAccess.Write)
Dim DES As New DESCryptoServiceProvider()
'Set secret key for DES algorithm.
'A 64-bit key and an IV are required for this provider.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
'Set the initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
'Create the DES encryptor from this instance.
Dim desencrypt As ICryptoTransform = DES.CreateEncryptor()
'Create the crypto stream that transforms the file stream by using DES encryption.
Dim cryptostream As New CryptoStream(fsEncrypted, _
desencrypt, _
CryptoStreamMode.Write)
'Read the file text to the byte array.
Dim bytearrayinput(fsInput.Length - 1) As Byte
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)
'Write out the DES encrypted file.
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)
cryptostream.Close()
System.IO.File.Delete(sInputFilename)
End Sub
Can anyone help me out with this? I can't figure out what I am doing wrong.
Use fsInput.Close() right before System.IO.File.Delete(sInputFilename)
Hope this helps

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?

Encryption keysize and algorithm

Here is some code that I have that works perfectly:
Sub EncryptFile(ByVal sInputFilename As String, _
ByVal sOutputFilename As String, _
ByVal sKey As String)
Dim fsInput As New FileStream(sInputFilename, _
FileMode.Open, FileAccess.Read)
Dim fsEncrypted As New FileStream(sOutputFilename, _
FileMode.Create, FileAccess.Write)
Dim DES As New DESCryptoServiceProvider()
'Set secret key for DES algorithm.
'A 64-bit key and an IV are required for this provider.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
'Set the initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
'Create the DES encryptor from this instance.
Dim desencrypt As ICryptoTransform = DES.CreateEncryptor()
'Create the crypto stream that transforms the file stream by using DES encryption.
Dim cryptostream As New CryptoStream(fsEncrypted, _
desencrypt, _
CryptoStreamMode.Write)
'Read the file text to the byte array.
Dim bytearrayinput(fsInput.Length - 1) As Byte
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)
'Write out the DES encrypted file.
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)
cryptostream.Close()
End Sub
Is it possible to change the keysize and maybe even choose between MD5 and SHA1 encryption with this code? If not, can someone point me in the right direction to find some that does?
thanks
Simon
DES is an encryption algorithm. If you want to use something else you should look at the TripleDESCryptoServiceProvider, or the AesCryptoServiceProvider (in the System.Security.Cryptography namespace).
MD5 and SHA1 are actually hashing algorithms. Effectively they are special case one-way encryption algorithms that can not be decrypted (so I don't think they are what you are looking for).
Just looking at the documentation for TripleDES and Aes classes it looks like you should be able to replace the line:
Dim DES As New DESCryptoServiceProvider()
with any of the other CryptoServiceProvider classes that provides a CreateEncryptor function. They also support a KeySize property that you can set. You might try something like:
Sub EncryptFile(ByVal sInputFilename As String, _
ByVal sOutputFilename As String, _
ByVal sKey As String, _
ByVal keysize as integer, _
ByVal algorithm as String)
Dim fsInput As New FileStream(sInputFilename, _
FileMode.Open, FileAccess.Read)
Dim fsEncrypted As New FileStream(sOutputFilename, _
FileMode.Create, FileAccess.Write)
Dim algorithm As SymmetricAlgorithm
Select Case algorithm
Case "DES": algorithm = New DESCryptoServiceProvider()
Case "3DES": algorithm = New TripleDESCryptoServiceProvider()
Case "AES": algorithm = New AESCryptoServiceProvider()
End Select
algorithm.KeySize = keysize
'Set secret key for the algorithm.
'A 64-bit key and an IV are required for this provider.
algorithm.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
'Set the initialization vector.
algorithm.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
'Create the encryptor from this instance.
Dim desencrypt As ICryptoTransform = algorithm.CreateEncryptor()
'Create the crypto stream that transforms the file stream by using encryption.
Dim cryptostream As New CryptoStream(fsEncrypted, _
desencrypt, _
CryptoStreamMode.Write)
'Read the file text to the byte array.
Dim bytearrayinput(fsInput.Length - 1) As Byte
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)
'Write out the DES encrypted file.
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)
cryptostream.Close()
End Sub
I haven't tried to compile the above sample but that you get you started I hope.