having problems with BinaryWriter and unicode RSA encrypted strings

OC-NightHawk

Member
Joined
Jul 24, 2004
Messages
13
the encryption and decryption are wrapped by these two functions that return stings.

Code:
Public Shared Function DecryptRSA(ByVal EncryptedText As String, ByVal iKey As String) As String
            Dim EncryptedDataBytes() As Byte
            Dim DecryptedText As String
            enter the full fledged private key to unlock decryption
            RSAKey.FromXmlString(iKey)
            If EncryptedText <> "" Then
                EncryptedDataBytes = RSAKey.Decrypt(Encoding.Unicode.GetBytes(EncryptedText), False)
                DecryptedText = Encoding.Unicode.GetString(EncryptedDataBytes)
            End If
            Return (DecryptedText)
        End Function

        Public Shared Function EncryptRSA(ByVal TextToEncrypt As String, ByVal iKey As String) As String
            Dim EncryptedDataBytes() As Byte
            Dim EncryptedData As String
            enter the public key it recieved when trading to unlock encryption
            RSAKey.FromXmlString(iKey)
            EncryptedDataBytes = RSAKey.Encrypt(Encoding.Unicode.GetBytes(TextToEncrypt), False)
            EncryptedData = Encoding.Unicode.GetString(EncryptedDataBytes)
            Return (EncryptedData)
        End Function

however

Code:
BW.Write(Encryption.EncryptRSA(Str(.LicenseType) & "," & _
                                                         Str(.DaysRemaining) & "," & .SerialNumber & "," & _
                                                         .LicenseID, Encryption.SharedClientPublicKey))

generates the following error attached a png.
 

Attachments

If I make the decrypt and encrypt functions use utf8 instead of unicode I get this error message.

the keys are created with thse functions

Code:
Public Function MakePublicRSAKey() As String
            Return (RSAKey.ToXmlString(False)) dont export the private key portion
        End Function

        Public Function MakePrivateRSAKey() As String
            Return (RSAKey.ToXmlString(True)) export the private key portion
        End Function

Any refrence to ServerSharedPublicKey or ClientSharedPublicKey are the two parts copy of the public key from one another.
 

Attachments

After seeing how much the text format mattered I attempted to run a encoder.convert to get the working file formats but Im still getting bad data errors.

Code:
Public Shared Function DecryptRSA(ByVal EncryptedText As String, ByVal iKey As String) As String
            Dim EncryptedDataBytes() As Byte
            Dim DecryptedText As String
            enter the full fledged private key to unlock decryption
            RSAKey.FromXmlString(iKey)
            If EncryptedText <> "" Then
                EncryptedDataBytes = Encoding.Unicode.GetBytes(EncryptedText)
                EncryptedDataBytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, EncryptedDataBytes)
                EncryptedDataBytes = RSAKey.Decrypt(EncryptedDataBytes, False)
                DecryptedText = Encoding.UTF8.GetString(EncryptedDataBytes)
            End If
            Return (DecryptedText)
        End Function

        Public Shared Function EncryptRSA(ByVal TextToEncrypt As String, ByVal iKey As String) As String
            Dim EncryptedDataBytes() As Byte
            Dim EncryptedData As String
            enter the public key it recieved when trading to unlock encryption
            RSAKey.FromXmlString(iKey)
            EncryptedDataBytes = RSAKey.Encrypt(Encoding.UTF8.GetBytes(TextToEncrypt), False)
            convert EncryptedDataBytes to unicode for the decryption process
            EncryptedDataBytes = Encoding.Convert(Encoding.UTF8, Encoding.Unicode, EncryptedDataBytes)
            EncryptedData = Encoding.Unicode.GetString(EncryptedDataBytes)

            Return (EncryptedData)
        End Function
 
Could you post the parts of your code where you actually call the routines to generate the keys? Are you generating the keys everytime or storing them somewhere in between executions?
 
This is from the client making its keys

Code:
Private Shared Sub PrepEncryption()

        With Encryption
            .PrepLicenseCodeBook()
            Get the clients public key
            .ClientPublicKey = .MakePublicRSAKey()
            .ClientPrivateRSAKey = .MakePrivateRSAKey()
        End With

        Now connect to the server and trade the RAS Public Keys.
        With ClientMessages
            .Message = .TradePublicKeys
        End With
        ConnectToServer()

    End Sub

These are the routines where the traded keys are put into variables to keep them handy.

Code:
Public Sub ClientProcessInfo(ByVal Mode As String, ByVal Info As String)

            Select Case Mode
                Case "LicenseInfo"
                    Dim Seperators() As Char = {","c}
                    Dim Words() As String
                    Dim Word As String
                    Dim OnWOrd As Integer

                    split the info into chunks
                    Words = Info.Split(Seperators)

                    put each chunk of info in its proper place
                    With Encryption.License
                        For Each Word In Words
                            Select Case OnWOrd
                                Case 0
                                    .LicenseType = Val(Word)
                                Case 1
                                    .DaysRemaining = Val(Word)
                                Case 2
                                    .SerialNumber = Word
                                Case 3
                                    .LicenseID = Word
                            End Select
                            OnWOrd = OnWOrd + 1
                        Next Word
                    End With
                Case "TradeKeys"
                    Encryption.SharedServerPublicKey = Info.Substring(10)
            End Select

        End Sub

        Public Sub ServerProcessInfo(ByVal Mode As String, ByVal info As String)
            Select Case Mode
                Case "TradeKeys"
                    Encryption.SharedClientPublicKey = info.Substring(10)
            End Select
        End Sub

Its a bit messy at the moment but this is the servers client handler that listens and responds to the client. Without encryption it works great but as soon as I turn RSA on not a single message can get through or decoded. Not sure if its a bad key or if it cant handle that type of data. I was considering making it so encrpting it would spit out a byte array. However the binaryreader wants to know how many bites the message is and I dont know how to get that info. So I set it up to pass strings and do conversion to get the bytes from the string. Maybe its having a problem readin ghte data after converting it back from a string. Any ideas? -> code in next post. 1 second please.
 
Code:
Dim ServerCommand As String

                Try
                    retrieve the network stream
                    Dim Stream As NetworkStream = Client.GetStream()

                    create a BinaryWriter and Binary reader for interacting with Binary streams
                    Dim BW As New BinaryWriter(Stream)
                    Dim BR As New BinaryReader(Stream)

                    Dim SW As New StreamWriter(Stream)
                    Dim SR As New StreamReader(Stream)


                    this command recieved will only ever be a request to connect
                    ServerCommand = BR.ReadString()

                    If ServerCommand = ClientMessages.RequestConnect Then
                        BW.Write(ServerMessages.AcknowledgeOK)
                        Console.WriteLine("Connection Accepted")
                        Do
                            ServerCommand = BR.ReadString() ServerCommand = BR.ReadString()
                            If ServerCommand <> "" Then
                                Select Case Encryption.EncryptionMode
                                    Case Encryption.EncryptionModeEnum.RSAEncription
                                        ServerCommand = Encryption.DecryptRSA(ServerCommand, _
                                                        Encryption.ServerPrivateRSAKey)
                                    Case Encryption.EncryptionModeEnum.RijndaelEncryption

                                End Select
                            End If
                            Select Case ServerCommand
                                Case ClientMessages.GetLicenseInfo
                                    Console.WriteLine("Server sending license information.")
                                    With Encryption.License
                                        Select Case Encryption.EncryptionMode
                                            Case Encryption.EncryptionModeEnum.UnEncrypted
                                                BW.Write(Str(.LicenseType) & "," & Str(.DaysRemaining) & "," & _
                                                         .SerialNumber & "," & .LicenseID)
                                            Case Encryption.EncryptionModeEnum.RSAEncription
                                                BW.Write(Encryption.EncryptRSA(Str(.LicenseType) & "," & _
                                                         Str(.DaysRemaining) & "," & .SerialNumber & "," & _
                                                         .LicenseID, Encryption.SharedClientPublicKey))
                                            Case Encryption.EncryptionModeEnum.RijndaelEncryption

                                        End Select
                                    End With
                                Case ClientMessages.TradePublicKeys
                                    Console.WriteLine("Server sending its public RSA key.")
                                    Select Case Encryption.EncryptionMode
                                        Case Encryption.EncryptionModeEnum.UnEncrypted
                                            BW.Write("PublicKey=" & Encryption.ServerPublicKey)
                                        Case Encryption.EncryptionModeEnum.RSAEncription
                                            BW.Write(Encryption.EncryptRSA("PublicKey=" & Encryption.ServerPublicKey, _
                                                                           Encryption.SharedClientPublicKey))
                                        Case Encryption.EncryptionModeEnum.RijndaelEncryption

                                    End Select
                                    Console.WriteLine("Server is waiting for the clients public RSA key.")
                                    Do
                                        get the message and decrypt it if needed
                                        ServerCommand = BR.ReadString() BR.ReadString()
                                        If ServerCommand <> "" Then
                                            Select Case Encryption.EncryptionMode
                                                Case Encryption.EncryptionModeEnum.RSAEncription
                                                    ServerCommand = Encryption.DecryptRSA(ServerCommand, _
                                                        Encryption.ServerPrivateRSAKey)
                                                Case Encryption.EncryptionModeEnum.RijndaelEncryption

                                            End Select
                                        End If
                                    Loop Until ServerCommand.Substring(0, 10) = "PublicKey="
                                    ServerProcessInfo("TradeKeys", ServerCommand)
                                    Console.WriteLine("Server confirms client public RSA key recieved.")
                                    Select Case Encryption.EncryptionMode
                                        Case Encryption.EncryptionModeEnum.UnEncrypted
                                            BW.Write(ServerMessages.AcknowledgeOK)
                                        Case Encryption.EncryptionModeEnum.RSAEncription
                                            BW.Write(Encryption.EncryptRSA(ServerMessages.AcknowledgeOK, _
                                                     Encryption.SharedClientPublicKey))
                                        Case Encryption.EncryptionModeEnum.RijndaelEncryption

                                    End Select
                                    Do
                                        wait to disconnect
                                        get the message and decrypt it if needed
                                        get the message and decrypt it if needed
                                        ServerCommand = BR.ReadString() BR.ReadString()
                                        If ServerCommand <> "" Then
                                            Select Case Encryption.EncryptionMode
                                                Case Encryption.EncryptionModeEnum.RSAEncription
                                                    ServerCommand = Encryption.DecryptRSA(ServerCommand, _
                                                        Encryption.ServerPrivateRSAKey)
                                                Case Encryption.EncryptionModeEnum.RijndaelEncryption

                                            End Select
                                        End If
                                    Loop Until ServerCommand = ClientMessages.Disconnect
                                    only change the encryption type before or after a client transaction
                                    changes in mid stream will lead do type mismatch errors when reading from BR
                                    Encryption.EncryptionMode = Encryption.EncryptionModeEnum.RSAEncription
                            End Select
                        Loop Until ServerCommand = ClientMessages.Disconnect
                        Select Case Encryption.EncryptionMode
                            Case Encryption.EncryptionModeEnum.UnEncrypted
                                BW.Write(ServerMessages.Disconnect)
                            Case Encryption.EncryptionModeEnum.RSAEncription
                                BW.Write(Encryption.EncryptRSA(ServerMessages.Disconnect, _
                                         Encryption.SharedClientPublicKey))
                            Case Encryption.EncryptionModeEnum.RijndaelEncryption

                        End Select
                    Else
                        couldnt connect
                    End If

                    close the connection socket
                    Console.WriteLine("Server Client Handeler exiting.")
                    Client.Close()
                Catch Err As Exception
                    Client.Close()
                    Console.WriteLine(Err.ToString())
                    MsgBox(Err.ToString, MsgBoxStyle.OKOnly)
                End Try

            End Sub

Sorry for the huge amount of code.
 
Stepping through both the client and server things seem to go smoothly at first and the client logs the messages
Attempting to connect to the server on port 8000.
LicenseServerTools.exe: Loaded c:\windows\assembly\gac\system.xml\1.0.5000.0__b77a5c561934e089\system.xml.dll, No symbols loaded.
Cennection established.
Client requesting to trade public RSA keys.
Client sending its public RSA key.
Client Disconnecting
The thread PrepEncryptionThread (0x1a3c) has exited with code 0 (0x0).
Attempting to connect to the server on port 8000.
Cennection established.

The server logs
Connection Accepted
Server sending its public RSA key.
Server is waiting for the clients public RSA key.
Server confirms client public RSA key recieved.
Server Client Handeler exiting.
The thread ServerClientHandler0 (0x2208) has exited with code 0 (0x0).
Connection Accepted

then its call to ServerCommand = BR.ReadString() (line 460 in LicenseEngine.vb) seems to return junk (most definately not a string) and this is what causes eit to fall over. Not sure why but it doesnt seem to be in response to anything the client is sending though....

I will try to have another look later but that seems to be where the problem lies.
 
Yeah the unencrypted part is fine no problems there. But once both the client and server have the public key of the others for RSA encryption they are supposed to encrypt their messages so that the other can decode it using their private RSA key. The junk is the encrypted message, or at least I think it is.

In the end RSA is only a minor role. It will only be used for the server to ask a question to the client to confirm its identiy and then send a key for encoding and decoding with RijndaelManaged. At leasts thats the game plan.
 
If it is sending the encrypted data then you should either pass it as a byte array or if sendingf as a string then use a string safe format (e.g. base64) as the string that is getting sent appears to have a lot o finvalid characters.
 
PlausiblyDamp, I dont know if the base64 did the trick or what but it works now. Heres the full code for the encryption class if you
 
Back
Top