none
How do I decrypt a value before adding it to my Listview? RRS feed

  • Question

  • Good evening,

    I have need to decrypt a value (ccNumber) being pulled from my MySQL database before it is assigned to my Listview. How do I do this?

    I managed to figure out how to encrypt it before it's inserted to the database (encryption code shown below), but I'm struggling with the decryption. As shown below in my code, I'm attempting to call the decryption sub-routine (DecryptCard) just before I iterate through the datatable (dbTable) and assign its values to my Listview (ListViewCard). However, only the first record succeeds then I get an error message (see images below).

    I received a suggestion on Stackoverflow.com as shown below, but still getting the same error message.  It appears the first record in the query is being decoded fine, but the second and subsequent records and causing an error.  I don't know what to do, any help would be appreciated.  If my approach is wrong and an entirely new approach would work, I'm open to the suggestion.  All I want to do is encrypt the credit card number before storing to DB and decrypt upon retrieval.  Thanks in advance for your assistance.


    CODE TO QUERY DATABASE AND LOAD DATA INTO LISTVIEW:

    Private Sub loadCard()
    
        Try
            'FOR MySQL DATABASE USE
            Dim dbQuery As String = ""
            Dim dbCmd As New MySqlCommand
            Dim dbAdapter As New MySqlDataAdapter
            Dim dbTable As New DataTable
            Dim i As Integer
    
            If dbConn.State = ConnectionState.Closed Then
                dbConn.ConnectionString = String.Format("Server={0};Port={1};Uid={2};Password={3};Database=accounting", FormLogin.ComboBoxServerIP.SelectedItem, My.Settings.DB_Port, My.Settings.DB_UserID, My.Settings.DB_Password)
                dbConn.Open()
            End If
    
            dbQuery = "SELECT *" & _
                       "FROM cc_master INNER JOIN customer ON customer.accountNumber = cc_master.customer_accountNumber " & _
                       "WHERE customer.accountNumber = '" & TextBoxAccount.Text & "'"
            With dbCmd
                .CommandText = dbQuery
                .Connection = dbConn
            End With
            With dbAdapter
                .SelectCommand = dbCmd
                .Fill(dbTable)
            End With
            ListViewCard.Items.Clear()
            For i = 0 To dbTable.Rows.Count - 1
                Call DecryptCard()
                With ListViewCard
                    .Items.Add(dbTable.Rows(i)("ccID"))
                    With .Items(.Items.Count - 1).SubItems
                        .Add(dbTable.Rows(i)("ccNumber"))
                        .Add(dbTable.Rows(i)("ccExpireMonth"))
                        .Add(dbTable.Rows(i)("ccExpireYear"))
                        .Add(dbTable.Rows(i)("ccCode"))
                        .Add(dbTable.Rows(i)("ccType"))
                        .Add(dbTable.Rows(i)("ccAuthorizedUseStart"))
                        .Add(dbTable.Rows(i)("ccAuthorizedUseEnd"))
                        .Add(dbTable.Rows(i)("nameCOMPANY"))
                        .Add(dbTable.Rows(i)("nameSALUTATION"))
                        .Add(dbTable.Rows(i)("nameLAST"))
                        .Add(dbTable.Rows(i)("nameFIRST"))
                    End With
                End With
            Next
        Catch ex As MySqlException
            MessageBox.Show("A DATABASE ERROR HAS OCCURED" & vbCrLf & vbCrLf & ex.Message & vbCrLf & _
                        vbCrLf + "Please report this to the IT/Systems Helpdesk at Ext 131.")
        End Try
        dbConn.Close()
    
    End Sub

    CODE THAT SHOULD DECRYPT THE VALUE (ccNumber):

    Public Sub DecryptCard()
        Dim DES As New System.Security.Cryptography.TripleDESCryptoServiceProvider
        Dim Hash As New System.Security.Cryptography.MD5CryptoServiceProvider
        Try
            DES.Key = Hash.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(My.Settings.Key))
            DES.Mode = System.Security.Cryptography.CipherMode.ECB
            Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = DES.CreateDecryptor
            Dim Buffer As Byte() = Convert.FromBase64String(dbTable.Rows(0)("ccNumber").ToString())
            dbTable.Rows(0)("ccNumber") = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
        Catch ex As Exception
            MessageBox.Show("The following error(s) have occurred: " & ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    HERE'S THE ENCRYPTION CODE:

    Public Sub encryptCard()
        Try
            Dim DES As New System.Security.Cryptography.TripleDESCryptoServiceProvider
            Dim Hash As New System.Security.Cryptography.MD5CryptoServiceProvider
            Dim encryptedCard As String
            DES.Key = Hash.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(My.Settings.Key))
            DES.Mode = System.Security.Cryptography.CipherMode.ECB
            Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = DES.CreateEncryptor
            Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(TextBoxCard.Text)
            encryptedCard = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
        Catch ex As Exception
            MessageBox.Show("The following error(s) have occurred: " & ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    APPLICATION SCREENSHOT #1:
    Immediately after query runs, this error pops up.  It will keep popping up until the last record and then the results are displayed (see next screenshot)


    APPLICATION SCREENSHOT #2:
    This is showing the result of my query in the ListView control.  As you can see, the Credit Card Number (ccNumber) is being decrypted correctly, but not the second record.





    • Moved by Chester Hong Wednesday, October 17, 2012 6:57 AM (From:Windows Forms General)
    Tuesday, October 16, 2012 4:14 AM

Answers

  • Have you tried TRIMming the field in question before passing the value off to the decryption routine?

    String.Trim(dbTable.Rows(0)("ccNumber")) 'Or similar trim syntax

    There might be trailing spaces in that field from the select statement.

    Wednesday, October 17, 2012 10:10 PM

All replies

  • Hi Kismet-Gerald,

    I will move the thread to Common Language Runtime forum. Your question is more about how to decrypt a value than using listview control.

    Sorry for any inconvenience.

    Best regards,


    Chester Hong
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, October 17, 2012 6:57 AM
  • Hi Kismet,

    Welcome to the MSDN Forum.

    Based on the MSDN document: http://msdn.microsoft.com/en-us/library/system.convert.frombase64string.aspx 

    s is composed of base-64 digits, white-space characters, and trailing padding characters. The base-64 digits in ascending order from zero are the uppercase characters "A" to "Z", lowercase characters "a" to "z", numerals "0" to "9", and the symbols "+" and "/".

    The white-space characters, and their Unicode names and hexadecimal code points, are tab (CHARACTER TABULATION, U+0009), newline (LINE FEED, U+000A), carriage return (CARRIAGE RETURN, U+000D), and blank (SPACE, U+0020). An arbitrary number of white-space characters can appear in s because all white-space characters are ignored.

    The valueless character, "=", is used for trailing padding. The end of s can consist of zero, one, or two padding characters.

    So I think you need to check your string which get from database.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, October 17, 2012 7:38 AM
    Moderator
  • Thanks Mike,

    I believe my string is fine, because I am encoding as Base64 - so the encoded string should be in Base64 before being stored in the database.

    I think something is happening that's causing the first record in the query to be decoded without a problem, but when the a subsequent record is being decoded - then the exception is thrown.

    Back to the drawing board for me - I'm determined to figure out what's going on.

    • Proposed as answer by Andrew Corley Wednesday, October 17, 2012 10:05 PM
    Wednesday, October 17, 2012 8:39 PM
  • Have you tried TRIMming the field in question before passing the value off to the decryption routine?

    String.Trim(dbTable.Rows(0)("ccNumber")) 'Or similar trim syntax

    There might be trailing spaces in that field from the select statement.

    Wednesday, October 17, 2012 10:10 PM