OC-NightHawk Posted July 24, 2004 Posted July 24, 2004 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. Quote
OC-NightHawk Posted July 24, 2004 Author Posted July 24, 2004 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. Quote
OC-NightHawk Posted July 25, 2004 Author Posted July 25, 2004 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 Quote
Administrators PlausiblyDamp Posted July 26, 2004 Administrators Posted July 26, 2004 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? Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
OC-NightHawk Posted July 26, 2004 Author Posted July 26, 2004 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. Quote
OC-NightHawk Posted July 26, 2004 Author Posted July 26, 2004 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. Quote
Administrators PlausiblyDamp Posted July 27, 2004 Administrators Posted July 27, 2004 Any chance you could zip up the projects and attach them as I seem to be missing somethings if I just cut and paste your code? Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
OC-NightHawk Posted July 27, 2004 Author Posted July 27, 2004 http://studentpages.scad.edu/~ejackm20/Downloads/LicenseServer.zip Quote
Administrators PlausiblyDamp Posted July 27, 2004 Administrators Posted July 27, 2004 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
OC-NightHawk Posted July 27, 2004 Author Posted July 27, 2004 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. Quote
Administrators PlausiblyDamp Posted July 27, 2004 Administrators Posted July 27, 2004 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
OC-NightHawk Posted July 28, 2004 Author Posted July 28, 2004 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 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.