• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3857
  • Last Modified:

Error for decryption: An unhandled exception of type 'System.ExecutionEngineException' occurred in mscorlib.dll

Hi,
please help, I'm trying to develop an application on encryption/decryption, the encryption part is working perfectly but the decryption part is giving this error: An unhandled exception of type 'System.ExecutionEngineException' occurred in mscorlib.dll. this is for mobile application with vb.net,  please check the code below:

Private Sub encrypt()

        Dim rsa As New RSACryptoServiceProvider
        Dim CypherTextBArray As Byte()

        rsa.FromXmlString(xmlPublicKey)

       Dim message As String = TextBox1.Text

        If message.Length > 58 Then MsgBox("You must use fewer than 59 characters") : Exit Sub
        PlainTextBArray = (New UnicodeEncoding).GetBytes(message)
        CypherTextBArray = rsa.Encrypt(PlainTextBArray, False)            'encrypt

        TextBox2.Text = ""
       
        For i As Integer = 0 To CypherTextBArray.Length - 1
            TextBox2.Text = Chr(CypherTextBArray(i))
            Response.Write(Chr(CypherTextBArray(i)))
        Next i
    End Sub


Private Sub decrypt(ByVal encrypt1 As Byte())

        Dim rsa As New RSACryptoServiceProvider
         Dim CypherTextBArray As Byte()
         rsa.FromXmlString(xmlKeys)
        Dim RestoredPlainText As Byte() = rsa.Decrypt(CypherTextBArray, False)  ERROR LINE

         For i As Integer = 0 To (RestoredPlainText.Length - 1) Step 2
            TextBox3.Text &= Chr(RestoredPlainText(i))
        Next i

    End Sub

 Private Sub encrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click
         encrypt()
 End Sub

 Private Sub decrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click
          decrypt()
End Sub


the error points at the line indicated, it seemingly it looses data somewhere because on decrypt CypherTextBArray is null.
0
LSJ
Asked:
LSJ
  • 9
  • 8
1 Solution
 
nayernaguibCommented:
Your problem is that you are trying to decrypt the uninitialized array CypherTextBArray!
Maybe you should try decrypting encrypt1 (if you are using it to carry encrypted data to decrypt() method).
Another solution is to store the desired data in CypherTextBArray *before* calling rsa.Decrypt().

________________

  Nayer Naguib
0
 
LSJAuthor Commented:
Thanks Nayer

sorry i made a mistake with the encrypt() method, i was trying to debug by using encrypt1 to carry encrypted data to decrypt() method, but it failed. the correct method is:
 
 Private Sub decrypt()

        Dim rsa As New RSACryptoServiceProvider
         Dim CypherTextBArray As Byte()
         rsa.FromXmlString(xmlKeys)
        Dim RestoredPlainText As Byte() = rsa.Decrypt(CypherTextBArray, False)  ERROR LINE

         For i As Integer = 0 To (RestoredPlainText.Length - 1) Step 2
            TextBox3.Text &= Chr(RestoredPlainText(i))
        Next i

    End Sub

about storing data in CypherTextBArray, i thought that it is already stored from the encrypt() method, or am I doing it wrongly?


0
 
nayernaguibCommented:
The CypherTextBArray byte array declared inside the encrypt() method goes out of scope when the method execution finishes. At this point the array does not exist anymore!

The CypherTextBArray byte array you declare inside decrypt() is a completely new one. When you send it to the rsa.Decrypt() method, an exception occurs because the array has not been initialized.

You can solve the problem by removing the

  Dim CypherTextBArray As Byte()

statement from both methods and declaring the array as a class member (put the statement just before the encrypt() method).

Note that it is also recommended that you initialize the array so that an exception does not occur if you call the decrypt method before the encrypt() method.

________________

  Nayer Naguib
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LSJAuthor Commented:
I've changed as you suggested but now is giving a Cryptographic exception: Bad data or Bad length from this line:  Dim RestoredPlainText As Byte() = rsa.Decrypt(CypherTextBArray, False)
can I send the code the original code before all the changes trying to debug so that you'll have a look at it. or another thing a collegue suggested ISPOSTBACK and viewstate for storing byte arrays, what do you say?
0
 
nayernaguibCommented:
The following code works fine (try it on a Windows Application):

_____________________________________________________________________

    Dim CypherTextBArray As Byte()
    Dim PlainTextBArray As Byte()
    Dim pk As String

    Private Sub encrypt()

        Dim rsa As New System.Security.Cryptography.RSACryptoServiceProvider
        pk = "<RSAKeyValue><Modulus>vWi7cHIntTcrwIoD0zj/fxoJCDfUHtC5xkMe8pJri7G+T6nKs4zRcLDWRDA0cNhf</Modulus><Exponent>AQAB</Exponent><P>5DwRzr4EPAk1NOUSwI/z1yBJzG2EyrhR</P><Q>1HOEBwbXvsrPQvV7C0MWtHJ22UWgwgmv</Q><DP>qQrEtbePM1gujErOJMl59O/5OOw02mDB</DP><DQ>bUFGqXJsavLTaaTidSU4PO4MjqnPBVqD</DQ><InverseQ>Y+XUwMmlI2G63reScAyc9PHvTPX2fwCg</InverseQ><D>o1Ku5cwZf0IegPzBRZ5NeYy6oxJ430V8n4BLZ8G8/N6kRHnXe70OyzwAylPtxjGh</D></RSAKeyValue>"
        rsa.FromXmlString(pk)

        Dim message As String = TextBox1.Text

        If message.Length > 58 Then MsgBox("You must use fewer than 59 characters") : Exit Sub
        PlainTextBArray = (New System.Text.UnicodeEncoding).GetBytes(message)
        CypherTextBArray = rsa.Encrypt(PlainTextBArray, False)            'encrypt

        TextBox2.Text = ""

        For i As Integer = 0 To CypherTextBArray.Length - 1
            TextBox2.Text &= Chr(CypherTextBArray(i))
        Next i
    End Sub


    Private Sub decrypt()

        Dim rsa As New System.Security.Cryptography.RSACryptoServiceProvider
        rsa.FromXmlString(pk)
        Dim RestoredPlainText As Byte() = rsa.Decrypt(CypherTextBArray, False)

        TextBox3.Text = ""

        For i As Integer = 0 To (RestoredPlainText.Length - 1) Step 2
            TextBox3.Text &= Chr(RestoredPlainText(i))
        Next i

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        encrypt()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        decrypt()
    End Sub

_____________________________________________________________________

Note the declaration of pk as a class member, and using it inside *both* encrypt and decrypt.
I copied the value of pk from existing code that uses CAPI (CryptoAPI) on Windows.

________________

  Nayer Naguib
0
 
nayernaguibCommented:
Sorry for posting that *very* long string!

________________

  Nayer Naguib
0
 
LSJAuthor Commented:
Thanks Nayer!

it worked perfectly for Windows Application, but now I want to use it for Mobile Application, i took your code as it is and is giving this error for mobile:
 System.ArgumentNullException: Value cannot be null. Parameter name: xmlString
this line: rsa.FromXmlString(pk)
 
is there any difference in coding, if one want to develop different applications?
would you please explain why is not working for mobile application.
0
 
LSJAuthor Commented:
if I initialize "pk" also in the decrypt() method, it is taking me back to the first error (System.ExecutionEngineException' occurred in mscorlib.dll)
0
 
nayernaguibCommented:
Make sure that under *no* condition will the application call decrypt() before encrypt()

The only explanation for the occurence of the two exceptions is that decrypt() is called first:

>  System.ArgumentNullException: Value cannot be null. Parameter name: xmlString

means that pk has not been initialized, which is impossible if encrypt() was called first, as pk will hold the given value before being used.

>  if I initialize "pk" also in the decrypt() method, it is taking me back to the first error (System.ExecutionEngineException' occurred in mscorlib.dll)

means that CypherTextBArray has not been initialized, which *also* means that encrypt() has not been called yet.

If this does not work, please post the complete code, so that I can take a better look at the problem.

________________

  Nayer Naguib
0
 
LSJAuthor Commented:
this is the original code for mobile application, i think is similar to yours

Imports MobileCrypt.Portal.DataAccessLayer
Imports System.Security.Cryptography
Imports System.Text


Public Class MobileWebForm1
    Inherits System.Web.UI.MobileControls.MobilePage

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents TextBox1 As System.Web.UI.MobileControls.TextBox
    Protected WithEvents TextBox2 As System.Web.UI.MobileControls.TextBox
    Protected WithEvents TextBox3 As System.Web.UI.MobileControls.TextBox
    Protected WithEvents Command1 As System.Web.UI.MobileControls.Command
    Protected WithEvents Command2 As System.Web.UI.MobileControls.Command
    Protected WithEvents Form1 As System.Web.UI.MobileControls.Form

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Dim xmlKeys As String                                             'A combination of both the public & private keys  
    Dim xmlPublicKey As String                                       'The public key only
    Dim PlainTextBArray As Byte()                                   'The plaintext message in a byte array
    Dim CypherTextBArray() As Byte                                'The cyphertext message in a byte array
    Dim rsa As New RSACryptoServiceProvider
 
    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       
        xmlKeys = rsa.ToXmlString(True)               'Hold both keys in a global variable that will be used in the decryption procedure  
        xmlPublicKey = rsa.ToXmlString(False)        'Hold the public key to be used in the encryption procedure
   End Sub
   
    Private Sub encrypt()

         rsa.FromXmlString(xmlPublicKey)                                                              'get the public key so you can encrypt the message:
         Dim message As String = TextBox1.Text                                                    'get the message
       
        If message.Length > 58 Then MsgBox("You must use fewer than 59 characters") : Exit Sub

        PlainTextBArray = (New UnicodeEncoding).GetBytes(message)     'transform message string into a byte array:
       
       CypherTextBArray = rsa.Encrypt(PlainTextBArray, False)               ' Encrypt

        TextBox2.Text = ""                                                                    'view the cyphertext in TextBox2:

        For i As Integer = 0 To CypherTextBArray.Length - 1
            TextBox2.Text = Chr(CypherTextBArray(i))
            Response.Write(Chr(CypherTextBArray(i)))
        Next i

    End Sub

    Private Sub Command1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click
        encrypt()
    End Sub

    Private Sub decrypt()

      rsa.FromXmlString(xmlKeys)                                               'get the keys, thereby creating an RSA object that's identical
                                                                                              ' to the one used in the Form_Load event when the keys were first built

    Dim RestoredPlainText As Byte() = rsa.Decrypt(CypherTextBArray, False)   'create a byte array and then put the decrypted plaintext into it

     ' Step through the two-byte unicode plaintext, displaying the restored  plaintext message
        For i As Integer = 0 To (RestoredPlainText.Length - 1) Step 2
            TextBox3.Text &= Chr(RestoredPlainText(i))
        Next i

    End Sub

    Private Sub Command2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command2.Click
        decrypt()
    End Sub
End Class
0
 
nayernaguibCommented:
Try the following (you only need to modify the methods listed below):

__________________________________________________________________

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Page.IsPostBack Then Exit Sub
        Session("keys") = rsa.ToXmlString(True)                
        Session("pk") = rsa.ToXmlString(False)        
    End Sub

    Private Sub encrypt()
        rsa.FromXmlString(Session("pk"))                                                              
        Dim message As String = TextBox1.Text                                                    
        If message.Length > 58 Then MsgBox("You must use fewer than 59 characters") : Exit Sub
        PlainTextBArray = (New UnicodeEncoding).GetBytes(message)  
        CypherTextBArray = rsa.Encrypt(PlainTextBArray, False)          
        TextBox2.Text = (New UnicodeEncoding).GetChars(CypherTextBArray)
    End Sub

    Private Sub decrypt()
        rsa.FromXmlString(Session("keys"))                                              
        CypherTextBArray = (New UnicodeEncoding).GetBytes(TextBox2.Text)  
        Dim RestoredPlainText As Byte() = rsa.Decrypt(CypherTextBArray, False)
        TextBox3.Text = (New UnicodeEncoding).GetChars(RestoredPlainText)
    End Sub

__________________________________________________________________

________________

  Nayer Naguib
0
 
LSJAuthor Commented:
Thank you very much, it worked.
God Bless You.

LSJ
0
 
LSJAuthor Commented:
Nayer!

i've got a problem again, the code is working perfectly so alone, but now I'm trying to introduce the database info. i.e.
I encrypt data and send it to the database to be stored (which is working fine), but the problem is when I retrieve the encrypted data
from DB to be decrypted. it gives a
1. System.Security.Cryptography.CryptographicException: Bad Data  OR
2. System.InvalidCastException: Specified cast is not valid

I think the problem is with byte/char convertion
0
 
nayernaguibCommented:
Maybe you should store the encrypted data in a binary field in your database.

If this does not help, then please post the code and the database structure. :-)

________________

  Nayer Naguib
0
 
LSJAuthor Commented:
please find the code and the corresponding database info. basically what i'm trying to do is, a user can enter login details for registration and can be stored in the database
encrypted, and when s/he login the application compares the entered details and the ones in the database (only password is encrypted for now), i want it to get the (encrypted)
value from the data, decrypt it and then compare (comparing is not a problem, the problem is encrypted value from database and decrypt)

Dim dbConn As String = ConfigurationSettings.AppSettings("dbConn")
Dim reader As SqlClient.SqlDataReader
Dim PlainTextBArray As Byte()       'The plaintext message in a byte array
Dim CypherTextBArray() As Byte  'The cyphertext message in a byte array
Dim rsa As New RSACryptoServiceProvider


    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     
        If Page.IsPostBack Then Exit Sub
        Session("xmlKeys") = rsa.ToXmlString(True)
        Session("xmlPublicKey") = rsa.ToXmlString(False)
    End Sub

Private Sub encrypt()

        rsa.FromXmlString(Session("xmlPublicKey"))
        Dim _name As String = name.Text
        Dim _surname As String = Surname.Text
        Dim psw As String = password.Text
        Dim encodedchar As String
       
        If psw.Length > 58 Then MsgBox("You must use fewer than 59 characters") : Exit Sub
        PlainTextBArray = (New UnicodeEncoding).GetBytes(psw)
        CypherTextBArray = rsa.Encrypt(PlainTextBArray, False)
        encodedchar = (New UnicodeEncoding).GetChars(CypherTextBArray)

        Dim arrparms() As SqlParameter = New SqlParameter(2) {}
        arrparms(0) = New SqlParameter("@name", _name)
        arrparms(1) = New SqlParameter("@surname", _surname)
        arrparms(2) = New SqlParameter("@password", encodedchar)

        Dim ds As DataSet = SqlHelper.ExecuteDataset(dbConn, CommandType.StoredProcedure, "testrsacrypro", arrparms)

    End Sub

Private Sub Command3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command3.Click
        encrypt()
        ActiveForm = Form3
    End Sub

Private Sub decrypt()
        Dim FFname As String = "Thenjiwe"
        Dim decrypted As String
        Dim arrparms() As SqlParameter = New SqlParameter(0) {}
        arrparms(0) = New SqlParameter("@name", FFname)
        Dim ds As DataSet = SqlHelper.ExecuteDataset(dbConn, CommandType.StoredProcedure, "decrypttestrsa", arrparms)

        If ds.Tables(0).Rows.Count = 0 Then
        Else
            Dim dr As DataRow
            Dim i As Integer

            For Each dr In ds.Tables(0).Rows
                rsa.FromXmlString(Session("xmlKeys"))
                CypherTextBArray = (New UnicodeEncoding).GetBytes(dr("Password"))
                Dim RestoredPlainText As Byte() = rsa.Decrypt(CypherTextBArray, False)

                List1.Items.Clear()
                While reader.Read()
                    List1.Items.Add((New UnicodeEncoding).GetChars(RestoredPlainText))
                    List1.DataBind()
                End While
               
            Next
        End If
    End Sub

  Private Sub Command4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command4.Click
        decrypt()
    End Sub

***********MSSQL database*********************************

this was just for testing if i'll be able to get encrypted data and decrypt it.
TABLE: TestCrypto
Name varchar(50)
Surname varchar(50)
password varchar(10)    (initially I used varchar, then I changed to image, text, varbinary, binary)

STORED PROCOCEDURES
1. FOR INSERTING THE VALUES
CREATE proc testrsacrypro
@name varchar(50),
@surname varchar(50),
@password varchar(10)    (initially I used varchar, then I changed to image, text, varbinary, binary)
as
insert into TestCrypto values(@name, @surname, @password)
GO

2. FOR SELECTION PASSWORD ONLY
CREATE proc decrypttestrsa
@name varchar(50)                                                
as
select password as [Password] from TestCrypto
where name = @name
GO

if you check the decrypt() method, I hard coded the parameter for name for using decrypttestrsa proc.
if using some of the datatype is not inserting.
0
 
LSJAuthor Commented:
just checking if you have find something for me, please help
0
 
nayernaguibCommented:
Hi LSJ!

You have one problem (at least), which is that each time you start a session, new keys are generated,
which cannot be used to decrypt data that has been encrypted using other keys!

Try generating the keys once, storing them somewhere inaccessible by users and reading them at the beginning of new sessions.

________________

  Nayer Naguib
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 9
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now