Solved

VB.NET : RSA Encryption : Encryption not always encrypting at 128 Bits

Posted on 2004-08-15
8
1,165 Views
Last Modified: 2012-05-05
Hi All,

I'm trying to encrypt a few details (4 variables to be exact) in this application that i'm creating using the RSA Encryption Method.

I can never seem to get it to encrypt all 4 correctly @ 128 bits, even though it says that the length of the encryption is 128 bits (tested using a MsgBox Feature)

The code seems fine to me... It comes back saying that it's encrypted at 128bits ok, but when decryption time comes, at least 1 of the 4 will cause an error in mscorlib.dll saying Bad Data on the line where the RSA.Decrypt method is called.

The Following is the Code of the clsEncryption.vb File

******************************************

Imports System.Security.Cryptography
Imports System.Text

Public Class clsEncryption

    Dim PlainText As Byte()
    Dim EncryptedText As Byte()
    Dim xmlKeys As String
    Dim xmlPublicKey As String

    Public Function ProcessEncryption(ByVal PrivateKey As String, ByVal PublicKey As String, ByVal Text As String)

        Try

            Dim RSA As RSACryptoServiceProvider = New RSACryptoServiceProvider

            RSA.FromXmlString(PublicKey)

            PlainText = (New UnicodeEncoding).GetBytes(Text)
            EncryptedText = RSA.Encrypt(PlainText, False)

            Dim FinalisedText As String = ""

            For i As Integer = 0 To EncryptedText.Length - 1
                FinalisedText += Chr(EncryptedText(i))
            Next i

            If FinalisedText.Length = 128 Then
                MsgBox("Encrypted @ 128 Bits OK", 64, "Encryption OK")
            Else
                MsgBox("Unable to Encrypt @ 128 Bits", 16, "Encryption Failed")
            End If

            Return FinalisedText

        Catch ex As Exception
            clsErrors.DisplayError(ex)
        End Try

    End Function

    Public Function ProcessDecryption(ByVal PrivateKey As String, ByVal PublicKey As String, ByVal EncryptedText As Byte())

        Try
            Dim RSA As RSACryptoServiceProvider = New RSACryptoServiceProvider

            RSA.FromXmlString(PrivateKey)

            PlainText = RSA.Decrypt(EncryptedText, False)

            Dim ProperText As String

            For i As Integer = 0 To (PlainText.Length - 1) Step 2
                ProperText += Chr(PlainText(i))
            Next i

            Return ProperText

        Catch ex As Exception
            clsErrors.DisplayError(ex)
        End Try

    End Function

    Public Function CreateKeys(ByVal Keys() As String)
        Dim rsa As New RSACryptoServiceProvider
        xmlKeys = rsa.ToXmlString(True)
        Keys(0) = xmlKeys
        xmlPublicKey = rsa.ToXmlString(False)
        Keys(1) = xmlPublicKey

        Return Keys

    End Function

End Class

******************************************

The Following is the code where the encryption process takes place

******************************************

    Private Sub btnSubmitAppDetails_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSubmitAppDetails.Click
        If txtSQLServer.Text = "" Then
            MsgBox("SQL Server Name Field Empty. Please Complete All Fields before Proceeding", 48, "SQL Server Field Empty")
            Exit Sub
        ElseIf txtSQLDatabase.Text = "" Then
            MsgBox("SQL Database Name Field Empty. Please Complete All Fields before Proceeding", 48, "SQL Database Name Field Empty")
            Exit Sub
        ElseIf txtSQLuser.Text = "" Then
            MsgBox("SQL Database User Name Field Empty. Please Complete All Fields before Proceeding", 48, "SQL Database User Name Field Empty")
            Exit Sub
        ElseIf txtSQLPassword.Text = "" Then
            MsgBox("SQL Database Password Field Empty. Please Complete All Fields before Proceeding", 48, "SQL Database Password Field Empty")
            Exit Sub
        End If

        Dim DBServer As String = txtSQLServer.Text
        Dim DBName As String = txtSQLDatabase.Text
        Dim DBUserName As String = txtSQLuser.Text
        Dim DBPassword As String = txtSQLPassword.Text

        lblStatus.Text = "Please Wait... Saving Data To Registry..."
        lblStatus.Update()
        lblStatus.Refresh()

        Dim Keys(1) As String

        Cryptography.CreateKeys(Keys)

        lblStatus.Text = "Please Wait... Creating Registry Keys..."
        lblStatus.Update()
        lblStatus.Refresh()
        RegKey = Registry.LocalMachine.CreateSubKey("SYSTEM\CurrentControlSet\Control\Class\{0F0F4125-DCDB-405E-AD8E-F0931279A240}\0000\AppData")
        RegKey.SetValue("PRKey", Keys(0))
        RegKey.SetValue("PUKey", Keys(1))

        lblStatus.Text = "Please Wait... Encrypting Details and Saving to System: 1 / 4..."
        lblStatus.Update()
        lblStatus.Refresh()
        DBServer = Cryptography.ProcessEncryption(Keys(0), Keys(1), DBServer)
        RegKey.SetValue("DBServer", DBServer)

        lblStatus.Text = "Please Wait... Encrypting Details and Saving to System: 2 / 4..."
        lblStatus.Update()
        lblStatus.Refresh()
        DBName = Cryptography.ProcessEncryption(Keys(0), Keys(1), DBName)
        RegKey.SetValue("DBName", DBName)

        lblStatus.Text = "Please Wait... Encrypting Details and Saving to System: 3 / 4..."
        lblStatus.Update()
        lblStatus.Refresh()
        DBUserName = Cryptography.ProcessEncryption(Keys(0), Keys(1), DBUserName)
        RegKey.SetValue("DBUser", DBUserName)

        lblStatus.Text = "Please Wait... Encrypting Details and Saving to System: 4 / 4..."
        lblStatus.Update()
        lblStatus.Refresh()
        DBPassword = Cryptography.ProcessEncryption(Keys(0), Keys(1), DBPassword)
        RegKey.SetValue("DBPass", DBPassword)

        lblStatus.Text = "Process Completed Successfully"
        lblStatus.Update()
        lblStatus.Refresh()

        RegKey.Close()

        Me.Dispose()

    End Sub

******************************************

The Following Code is where the Decryption takes place

******************************************

... ... ...

            'Decrypt Registry Data and Save to Global Variables

            RegKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Control\Class\{0F0F4125-DCDB-405E-AD8E-F0931279A240}\0000\AppData", False)

            Dim EncryptedVariable As Byte()
            Dim TextVariable As String

            Dim PrivateKey As String = RegKey.GetValue("PRKey")
            Dim PublicKey As String = RegKey.GetValue("PUKey")

            EncryptedVariable = System.Text.Encoding.Default.GetBytes(RegKey.GetValue("DBServer"))
            TextVariable = Cryptography.ProcessDecryption(PrivateKey, PublicKey, EncryptedVariable)
            SQLServer = TextVariable

            EncryptedVariable = System.Text.Encoding.Default.GetBytes(RegKey.GetValue("DBName"))
            TextVariable = Cryptography.ProcessDecryption(PrivateKey, PublicKey, EncryptedVariable)
            SQLDBName = TextVariable

            EncryptedVariable = System.Text.Encoding.Default.GetBytes(RegKey.GetValue("DBUser"))
            TextVariable = Cryptography.ProcessDecryption(PrivateKey, PublicKey, EncryptedVariable)
            SQLUser = TextVariable

            EncryptedVariable = System.Text.Encoding.Default.GetBytes(RegKey.GetValue("DBPass"))
            TextVariable = Cryptography.ProcessDecryption(PrivateKey, PublicKey, EncryptedVariable)
            SQLPassword = TextVariable

... ... ...

******************************************

If Anyone can provide some assistance into why it aint encrypting/decrypting correctly it'll be greatly appreciated

Many thanks in Advance

Kind Regards,

Ray.
0
Comment
Question by:RayFrangie
  • 4
  • 4
8 Comments
 
LVL 37

Accepted Solution

by:
gregoryyoung earned 500 total points
ID: 11804647
shouldnt those variables be byte arrays not strings ?

Also just poking through I found this which may help you out. It works around the issue by converting the byte arrays to base64 (thus they can be stored in strings)

        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

Cheers,

Greg
0
 
LVL 1

Author Comment

by:RayFrangie
ID: 11809608
Hi Greg,

Many thanks for your reply.

Quick Question (I know this may sound stupid):

KeyExchangeFormatter and KeyExchangeDeformatter come up as Not Declared

What am I missing? Import Statetments are:

Imports System.Security.Cryptography
Imports System.Text
Imports System.IO


Any help is greatly appreciated

Kind Regards,

Ray
0
 
LVL 1

Author Comment

by:RayFrangie
ID: 11809854
Hi Greg,

Skip that last comment, i managed to find that post where you got that code from (on vbCity)

Couple of lines did the trick:

    Shared KeyExchangeFormater As RSAOAEPKeyExchangeFormatter = New RSAOAEPKeyExchangeFormatter
    Shared KeyExchangeDeformatter As RSAOAEPKeyExchangeDeformatter = New RSAOAEPKeyExchangeDeformatter

Although Quick Question.... Isn't OEAP Limited to Windows XP and Later???

Let me know

Kind Regards,

Ray.
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11810647
I grabbed it more so to show the change of using byte arrays and base 64 to make strings ...
GetStringFromByteArray and GetByteArrayFromString
0
 
LVL 1

Author Comment

by:RayFrangie
ID: 11810688
Its cool, its solved the problem and the points are all yours

Just a quick Question as per the above post:

... ... ...

    Shared KeyExchangeFormater As RSAOAEPKeyExchangeFormatter = New RSAOAEPKeyExchangeFormatter
    Shared KeyExchangeDeformatter As RSAOAEPKeyExchangeDeformatter = New RSAOAEPKeyExchangeDeformatter

Although Quick Question.... Isn't OEAP Limited to Windows XP and Later???


Many thanks and Regards,

Ray.
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11810777
Use RSAOAEPKeyExchangeDeformatter to receive the key exchange and extract the secret information from it.

CAUTION   It is highly recommended that you not attempt to create your own key exchange method from the basic functionality provided, because many details of the operation must be performed carefully in order for the key exchange to be successful.
Requirements
Namespace: System.Security.Cryptography

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family

so I guess it may work.
0
 
LVL 1

Author Comment

by:RayFrangie
ID: 11810810
Hmmm... Interesting... I thought OEAP was only limited to XP and above...

Oh Well.... Only One way to find out...

Nevertheless, i'm now able to progress in this application thanks to you

Many thanks

Regards,

Ray.
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11810938
Glad to help.

Cheers,

Greg
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question