1

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:

Community
  • 1
  • 1
prizm1
  • 363
  • 1
  • 11

1 Answers1

0

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. :)

prizm1
  • 363
  • 1
  • 11