Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

the encryption and decryption are wrapped by these two functions that return stings.

 

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

 

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

 

generates the following error attached a png.

Posted

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

 

Public Function MakePublicRSAKey() As String
           Return (RSAKey.ToXmlString(False)) 'don't 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.

Posted

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

 

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

Posted

This is from the client making its keys

 

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.

 

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 can't 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 don't 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.

Posted

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
                       'couldn't 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.

  • Administrators
Posted

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 it's 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 doesn't 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.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

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.

Posted

PlausiblyDamp, I don't know if the base64 did the trick or what but it works now. Heres the full code for the encryption class if you�re interested. Thanks for the help. Without that base64 suggestion I would never have thought to look in this direction.

 

Public Class Encryption

       'create the Asymmetrical cryptography object
       Public Shared RSAKey As New RSACryptoServiceProvider
       Shared KeyExchangeFormater As RSAOAEPKeyExchangeFormatter = New RSAOAEPKeyExchangeFormatter
       Shared KeyExchangeDeformatter As RSAOAEPKeyExchangeDeformatter = New RSAOAEPKeyExchangeDeformatter

       Public Shared PrivateRSAKey As String
       Public Shared PublicRSAKey As String
       Public Shared SharedKey As String
       
       'create the symmetrical cryptography object
       Private Shared Rijndael As New RijndaelManaged

       Public Shared EncryptionMode As EncryptionModeEnum

       Public Enum EncryptionModeEnum
           UnEncrypted = 0
           RSAEncription = 1
           RijndaelEncryption = 2
       End Enum

       Public Shared License As LicenseStruct

       Public Structure LicenseStruct
           Dim LicenseType As LicenseTypeEnum
           Dim LicenseName() As String
           Dim DaysRemaining As Integer
           Dim SerialNumber As String
           Dim LicenseID As String
       End Structure

       Public Enum LicenseTypeEnum
           CommercialPerpetual = 0
           CommercialOneYear = 1
           EducationalPerpetual = 2
           EducationalOneYear = 3
           NoLicense = 4
           InvalidLicense = 5
       End Enum

       Public Sub PrepLicenseCodeBook()
           With License
               ReDim .LicenseName(5)
               .LicenseName(0) = "Commercial Perpetual"
               .LicenseName(1) = "Commercial One Year"
               .LicenseName(2) = "Educational Perpetual"
               .LicenseName(3) = "Educational One Year"
               .LicenseName(4) = "NoLicense"
               .LicenseName(5) = "InvalidLicense"
               'debug to be removed once real licenses are in place
               .SerialNumber = "0123456789"
               .LicenseID = "Test License"
           End With

       End Sub

       Public Function MakePublicRSAKey() As String
           RSAKey.ExportParameters(False)
           Return (RSAKey.ToXmlString(False)) 'don't export the private key portion
       End Function

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

       Public Shared Function DecryptRSA(ByVal EncryptedText As String) As String

           Dim EncryptedDataBytes As Byte()
           Dim DecryptedDataBytes As Byte()
           Dim DecryptedText As String
           
           Try

               'enter the full fledged private key to unlock decryption
               RSAKey.FromXmlString(PrivateRSAKey)
               KeyExchangeDeformatter.SetKey(RSAKey)

               'decode String to byte array of encrypted data
               EncryptedDataBytes = System.Convert.FromBase64String(EncryptedText)

               'decrypt the exchange data with the deformatter
               DecryptedDataBytes = KeyExchangeDeformatter.DecryptKeyExchange(EncryptedDataBytes)

               'convert the byte array into a string
               DecryptedText = GetStringFromByteArray(DecryptedDataBytes)

               Return (DecryptedText)

           Catch ex As Exception
               Console.WriteLine(Err.ToString())
               MsgBox(Err.ToString, MsgBoxStyle.OKOnly)
           End Try

       End Function

       Public Shared Function EncryptRSA(ByVal TextToEncrypt As String) As String

           Dim EncryptedDataBytes As Byte()
           Dim EncryptedData As String
           Dim PlainTextBytes As Byte()
           
           Try

               'enter the public key it recieved when trading to unlock encryption
               RSAKey.FromXmlString(SharedKey)
               KeyExchangeFormater.SetKey(RSAKey)

               'convert the text into byte form in preperation to be encrypted
               PlainTextBytes = (New ASCIIEncoding).GetBytes(TextToEncrypt)

               'encrypt the session key with the formatter
               EncryptedDataBytes = KeyExchangeFormater.CreateKeyExchange(PlainTextBytes)

               'convert the EncryptedDataBytes array into a base64 string
               EncryptedData = System.Convert.ToBase64String(EncryptedDataBytes)

               Return (EncryptedData)

           Catch ex As Exception
               Console.WriteLine(Err.ToString())
               MsgBox(Err.ToString, MsgBoxStyle.OKOnly)
           End Try

       End Function

#Region "Encryption Helpers"

       Private Shared Function GetByteArrayFromString(ByVal Text As String) As Byte()
           Dim b As Byte()
           Dim i As Integer

           ReDim b(Text.Length - 1)
           For i = 0 To Text.Length - 1
               b(i) = Asc(Mid(Text, i + 1, 1))
           Next
           Return b
       End Function

       Private Shared Function GetSubArray(ByRef bArray As Byte(), ByVal Start As Integer, ByVal Length As Integer) As Byte()
           Dim b As Byte()
           Dim i As Integer

           ReDim b(Length)
           For i = 0 To Length
               b(i) = bArray(Start + i)
           Next
           Return b
       End Function

       Private Shared Function GetStringFromByteArray(ByRef bArray As Byte()) As String
           Dim s As String
           Dim i As Integer

           For i = 0 To bArray.Length - 1
               s &= Chr(bArray(i))
           Next
           Return s
       End Function

#End Region

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...