Solved

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

Posted on 2004-08-15
8
1,170 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Help with converting xml file to excel using VB.NET 3 30
VB.Net. Reading xml value 6 36
Convert Ctime to date time in textfile? 7 59
Access/Visual Basic Question 3 41
Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

713 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