Solved

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

Posted on 2004-08-15
8
1,156 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
I grabbed it more so to show the change of using byte arrays and base 64 to make strings ...
GetStringFromByteArray and GetByteArrayFromString
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 1

Author Comment

by:RayFrangie
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Glad to help.

Cheers,

Greg
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

771 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now