views:

95

answers:

2

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
+2  A: 

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.

Hans Passant
Is not broken that. csDecrypt.Read() returns an integer noy a byte array.
BulgedSnowy
Yes, that integer is *very* important. It tells you how many bytes to write to the output file.
Hans Passant
But using File.WriteAllBytes don't need the byte lenght
BulgedSnowy
Do not use File.WriteAllBytes then. use FileStream.Write
Michał Piaskowski
Still creates a filesize bigger than the original because it uses the byte length of the encrypted byte array, not from the original file.
BulgedSnowy
Not sure what size 2-by-4 I need to operate to make you see that you can't use the Length of the byte array. Make the array twice as big, see what happens to the file size. Your downvote is not appreciated.
Hans Passant
my downvote? I cant downvote until my reputation reaches 100...and i think that 41 is not 100...
BulgedSnowy
My apologies, it must have been another drive-by voter that didn't care to post a better answer.
Hans Passant
No problem, it happens.
BulgedSnowy
+1  A: 

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
Sein Kraft
Thanks, it works perfect!
BulgedSnowy