Search code examples
.netvb.netencryptionaesrijndael

AES-functions always reply with empty results


today I've got a question about my current Visual Basic project I'm going for. My intention is to serve one or more encrypted Configuration-files for my program in the same directory where the executable is placed in. Because most likely the (en/de)cryption will be processed twice (username and password), I want to (en/de)crypt directly from String to String. I hope that this will reduce the hassles with temporary files and might be useful later on.

With the help of this great site and another tutorial I came as far, that at least the compiler doesn't complain anymore. :) So far, so good...

My code is the following:

   Private Function produceKeyandIV(ByVal Password As String) As Object()
    Dim ByteArray(Password.Length) As Byte, Key(31) As Byte, IV(15) As Byte
    ByteArray = System.Text.Encoding.ASCII.GetBytes(Password)
    Dim SHA_FUNCTION As New System.Security.Cryptography.SHA512Managed
    Dim HashResult As Byte() = SHA_FUNCTION.ComputeHash(ByteArray)
    Array.Copy(HashResult, Key, 32)
    Array.Copy(HashResult, 32, IV, 0, 16)
    Dim obj(2) As Object
    obj(0) = Key
    obj(1) = IV
    Return obj
End Function
Private Function GenerateStreamFromString(ByVal myString As String) As Stream
    Dim ret_stream As MemoryStream = New MemoryStream()
    Dim stream_writer As StreamWriter = New StreamWriter(ret_stream, Encoding.Default)
    stream_writer.Write(myString)
    stream_writer.Flush()
    ret_stream.Position = 0
    Return ret_stream
End Function
Public Function DecryptStringReturnString(ByVal EncryptedString As String, ByVal Key As String) As String
    Dim CryptographyParameters As Object() = produceKeyandIV(Key)
    Try
        Dim byteBuffer(4096) As Byte
        Dim memoryStreamIn As Stream = GenerateStreamFromString(EncryptedString)
        Dim memoryStreamOut As MemoryStream = New MemoryStream()
        Dim positionInString As Long = 0
        Dim StringLength As Long = EncryptedString.Length()
        Dim bytesInBlockProcessed As Integer = 0
        Dim cryptServiceProvRijn As New System.Security.Cryptography.RijndaelManaged
        Using sCryptoStream = New CryptoStream(memoryStreamOut, _
                                              cryptServiceProvRijn.CreateDecryptor(CryptographyParameters(0), CryptographyParameters(1)), _
                                              CryptoStreamMode.Write)
            While positionInString < StringLength
                bytesInBlockProcessed = memoryStreamIn.Read(byteBuffer, 0, 4096)
                sCryptoStream.Write(byteBuffer, 0, bytesInBlockProcessed)
                positionInString = positionInString + (bytesInBlockProcessed)
            End While
        End Using
        memoryStreamIn.Close()
        memoryStreamOut.Position = 0
        Dim stream_reader As StreamReader = New StreamReader(memoryStreamOut)
        Return stream_reader.ReadToEnd()
    Catch ex As Exception

    End Try
    Return Nothing
End Function
Public Function EncryptStringReturnString(ByVal DecryptedString As String, ByVal Key As String) As String
    Dim CryptographyParameters As Object() = produceKeyandIV(Key)
    Try
        Dim byteBuffer(4096) As Byte
        Dim memoryStreamIn As Stream = GenerateStreamFromString(DecryptedString)
        Dim memoryStreamOut As MemoryStream = New MemoryStream()
        Dim positionInString As Long = 0
        Dim StringLength As Long = DecryptedString.Length()
        Dim bytesInBlockProcessed As Integer = 0
        Dim cryptServiceProvRijn As New System.Security.Cryptography.RijndaelManaged
        Using sCryptoStream = New CryptoStream(memoryStreamOut, _
                                              cryptServiceProvRijn.CreateEncryptor(CryptographyParameters(0), CryptographyParameters(1)), _
                                              CryptoStreamMode.Write)
            While positionInString < StringLength
                bytesInBlockProcessed = memoryStreamIn.Read(byteBuffer, 0, 4096)
                sCryptoStream.Write(byteBuffer, 0, bytesInBlockProcessed)
                positionInString = positionInString + (bytesInBlockProcessed)
            End While
            memoryStreamIn.Close()
            memoryStreamOut.Position = 0
            Dim stream_reader As StreamReader = New StreamReader(memoryStreamOut)
            Return stream_reader.ReadToEnd()
        End Using
    Catch ex As Exception

    End Try
    Return Nothing
End Function

The problem is if I call the function and let me Print give the results, they are always empty. Maybe somebody else got an idea why? :)

Thanks in advance for your help...

Useful resources:


Solution

  • There was an instruction missing. According to this website FlushFinalBlock() is needed, in order to finalize the changes made to the CryptoStream. People over there also recommend to actually store the data in Byte-Arrays instead of converted Strings. Which will I will do in the further developement, only in the end, if the configuration needs to be plain readable it will get converted back to "readable" text.

    Heres my "fixed" version of my previous source code:

    Imports System.IO
    Imports System.Security.Cryptography
    Imports System.Text
    
    Module sandbox
        Private Function produceKeyandIV(ByVal Password As String) As Object()
            Dim ByteArray(Password.Length) As Byte, Key(31) As Byte, IV(15) As Byte
            ByteArray = System.Text.Encoding.ASCII.GetBytes(Password)
            Dim SHA_FUNCTION As New System.Security.Cryptography.SHA512Managed
            Dim HashResult As Byte() = SHA_FUNCTION.ComputeHash(ByteArray)
            Array.Copy(HashResult, Key, 32)
            Array.Copy(HashResult, 32, IV, 0, 16)
            Dim obj(2) As Object
            obj(0) = Key
            obj(1) = IV
            Return obj
        End Function
        Private Function GenerateStreamFromString(ByVal myString As String) As Stream
            Dim ret_stream As MemoryStream = New MemoryStream()
            Dim stream_writer As StreamWriter = New StreamWriter(ret_stream, Encoding.Default)
            stream_writer.Write(myString)
            stream_writer.Flush()
            ret_stream.Position = 0
            Return ret_stream
        End Function
        Public Function DecryptByteArrayReturnByteArray(ByVal Encrypted As Byte(), ByVal Key As String) As Byte()
            Dim CryptographyParameters As Object() = produceKeyandIV(Key)
            Try
                Dim byteBuffer(4096) As Byte
                Dim memoryStreamIn As Stream = New MemoryStream(Encrypted)
                Dim memoryStreamOut As MemoryStream = New MemoryStream()
                Dim position As Long = 0
                Dim bytesInBlockProcessed As Integer = 0
                Dim cryptServiceProvRijn As New System.Security.Cryptography.RijndaelManaged
                Using sCryptoStream = New CryptoStream(memoryStreamOut, _
                                                      cryptServiceProvRijn.CreateDecryptor(CryptographyParameters(0), CryptographyParameters(1)), _
                                                      CryptoStreamMode.Write)
                    While position < Encrypted.Count()
                        bytesInBlockProcessed = memoryStreamIn.Read(byteBuffer, 0, 4096)
                        sCryptoStream.Write(byteBuffer, 0, bytesInBlockProcessed)
                        sCryptoStream.Flush()
                        position = position + (bytesInBlockProcessed)
                    End While
                    memoryStreamIn.Close()
                    sCryptoStream.FlushFinalBlock() ' Needed to close the CryptoStream properly (a simple flush is not enough)
                    Return memoryStreamOut.ToArray ' Independent from actual Streamposition
                End Using
            Catch ex As Exception
    
            End Try
            Return Nothing
        End Function
        Public Function EncryptByteArrayReturnByteArray(ByVal Decrypted As Byte(), ByVal Key As String) As Byte()
            Dim CryptographyParameters As Object() = produceKeyandIV(Key)
            Try
                Dim byteBuffer(4096) As Byte
                Dim memoryStreamIn As Stream = New MemoryStream(Decrypted)
                Dim memoryStreamOut As MemoryStream = New MemoryStream()
                Dim position As Long = 0
                Dim bytesInBlockProcessed As Integer = 0
                Dim cryptServiceProvRijn As New System.Security.Cryptography.RijndaelManaged
                Using sCryptoStream = New CryptoStream(memoryStreamOut, _
                                                      cryptServiceProvRijn.CreateEncryptor(CryptographyParameters(0), CryptographyParameters(1)), _
                                                      CryptoStreamMode.Write)
                    While position < Decrypted.Count()
                        bytesInBlockProcessed = memoryStreamIn.Read(byteBuffer, 0, 4096)
                        sCryptoStream.Write(byteBuffer, 0, bytesInBlockProcessed)
                        sCryptoStream.Flush()
                        position = position + (bytesInBlockProcessed)
                    End While
                    memoryStreamIn.Close()
                    sCryptoStream.FlushFinalBlock() ' Needed to close the CryptoStream properly (a simple flush is not enough)
                    Return memoryStreamOut.ToArray ' Independent from actual Streamposition
                End Using
            Catch ex As Exception
    
            End Try
            Return Nothing
        End Function
        Sub Main()
            Console.Write("Passwort: ")
            Dim pwd = Console.ReadLine()
            Dim x As String = New String((System.Text.Encoding.Default.GetChars(DecryptByteArrayReturnByteArray(EncryptByteArrayReturnByteArray(System.Text.Encoding.Default.GetBytes(pwd), pwd), pwd))))
            Console.Write(x)
            Console.ReadLine()
        End Sub
    
    End Module
    

    If you think there are issues or flaws in the code, please point them out for me. I'd appreciate that very much. :)