Solved

Encrypting and Decrypting the password to and from a MySQL database

Posted on 2004-03-23
6
1,135 Views
Last Modified: 2013-12-25
I need to encrypt the passwords that i save to the database... With this, I then need to verify (by decrypting the saved password) if the password is valid on my login screen... How is this possible?? I am using Visual Basic 6.0 with a MySQL database...

I tried using the AES_ENCRYPT(string,key_string) and AES_DECRYPT(string,key_string) functions... I can see other characters in the database once I check the values I inserted so this works fine... But I cannot decrypt the same values... Which means, I might probably have not encrypted it right...

If possible, please provide me with a complete example of the correct use of these two functions in INSERTing an encrypted database and COMPARING a password typed in a textbox field to a decrypted one saved in the database...

Thanks...
0
Comment
Question by:dsound
  • 2
6 Comments
 
LVL 1

Expert Comment

by:VB-Expert
ID: 10668035
Hello dsound,

When using Passwords, (encryption), the recommended procedure is to encrypt the users entry and verify this against the encrypted password.

Decrypting passwords within programs,  leaves the syst4em open to hackers, and other malicious users.

VB-Expert...
0
 
LVL 1

Accepted Solution

by:
savvage earned 20 total points
ID: 10682018
Exactly. Furthermore, I suggest you use your own Encryption method, i.e. RSA, RSA MD5, etc.

I use for several purposes 128-bit RSA encryption mainly because I understand it better. You can find pre-fabricated RSA (MD5) encryption (or decryption) examples on the web.

Also, I suggest you avoid having your program actually decrypting the files. A better solution would be this:

Let's say you want to secure a file with a password.

Using RSA encryption, we encrypt the file using a random encryption key that is generated as a result of the password. You can devise your own very simple function to create a number from a word. Note that the result of the function must always give the same value, so no Randoms or Timers in the function!

The whole file is now encrypted with the encryption key. To decrypt it, however, we will be needing the decryption key aswell. We now include this code, encrypted in the file. However, we can't encrypt the code in the same way as the rest of the file, because it would be impossible to decrypt it, if you don't know what the decryption key is! Instead, encrypt the code reversely. That is to say: if you 'decode' the code with the encryption key, the correct answer is given. With a simple formula you can turn the RSA around to do this trick.

What we have now, is a password protected file that is split in two parts:
One part consists of the password and the rest of the file, and can be decoded with the decryption key.
The other part consists of the decryption key and can be decoded with the encryption key.

If the user wants to open the file, he has to fill in the password. The program DOESN'T KNOW what this password is. It simply encrypts the password with it's matching encryption key, and checks to see if it matches the encrypted code in the file. If so, then it will use the code to decrypt the decryption key, hereby allowing the program to decrypt the rest of the file.

Low and behold: all information is intact!

The level of security can easily be altered by changing the greatness of the intial prime numbers P and Q. To encrypt a database (containing binary data) you will need at least 256-bit encryption, because the product of P and Q must be at least 256. This is relatively insecure, so you'll be needing the product of P and Q to be at least 512 bits long! You might want to look around for a C++ or C# RSA library to do this for you, since VB isn't that great in 'big numbers'.

Good luck, I hope I gave you a few ideas. Here's where to learn more about RSA:

http://home.ozonline.com.au/davmac/davpage/algrthm/pkc.htm
http://www.cs.utexas.edu/users/plaxton/c/337/slides/Cryptography-3.pdf

Here you can find a RSA MD5 wrapper:
http://www.esquadro.com.br/md5bas.zip
0
 
LVL 1

Expert Comment

by:savvage
ID: 10703409
Dsound, if this answered your question, please award the points. Otherwise be more specific as to what your problem is.

Thanks, and good luck!
0
 

Expert Comment

by:dnhughes
ID: 10790764
Dsound,

I just did the same thing that you are asking about. My solution was to use the Windows crypto lib to do most of the work for me. Using MD5 I hashed the password and store the hash in the DB. When a user tries to log in I hash the password they are attmpting to use and see if the hash codes match. Below is some modified code from http://www.mvps.org/emorcillo/vb6/crypto/index.shtml

Hope this helps
---
Option Explicit

Private Declare Function CryptAcquireContext Lib "advapi32.dll" _
   Alias "CryptAcquireContextA" ( _
   ByRef phProv As Long, _
   ByVal pszContainer As String, _
   ByVal pszProvider As String, _
   ByVal dwProvType As Long, _
   ByVal dwFlags As Long) As Long

Private Declare Function CryptReleaseContext Lib "advapi32.dll" ( _
   ByVal hProv As Long, _
   ByVal dwFlags As Long) As Long

Private Declare Function CryptCreateHash Lib "advapi32.dll" ( _
   ByVal hProv As Long, _
   ByVal Algid As Long, _
   ByVal hKey As Long, _
   ByVal dwFlags As Long, _
   ByRef phHash As Long) As Long

Private Declare Function CryptDestroyHash Lib "advapi32.dll" ( _
   ByVal hHash As Long) As Long

Private Declare Function CryptHashData Lib "advapi32.dll" ( _
   ByVal hHash As Long, _
   pbData As Any, _
   ByVal dwDataLen As Long, _
   ByVal dwFlags As Long) As Long

Private Declare Function CryptGetHashParam Lib "advapi32.dll" ( _
   ByVal hHash As Long, _
   ByVal dwParam As Long, _
   pbData As Any, _
   pdwDataLen As Long, _
   ByVal dwFlags As Long) As Long

Private Const SERVICE_PROVIDER As String = "Microsoft Base Cryptographic Provider v1.0"

Private Const PROV_RSA_FULL = 1

Private Const CRYPT_VERIFYCONTEXT = &HF0000000
Private Const CRYPT_NEWKEYSET = &H8

Private Const ALG_CLASS_HASH = 32768

Private Const ALG_TYPE_ANY = 0

Private Const ALG_SID_MD2 = 1
Private Const ALG_SID_MD4 = 2
Private Const ALG_SID_MD5 = 3
Private Const ALG_SID_SHA1 = 4

Enum HashAlgorithm
   MD2 = ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD2
   MD4 = ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD4
   MD5 = ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD5
   SHA1 = ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA1
End Enum

Private Const HP_HASHVAL = 2
Private Const HP_HASHSIZE = 4

Function HashString( _
   ByVal str As String, _
   Optional ByVal Algorithm As HashAlgorithm = MD5) As String
   
    Dim hCtx As Long
    Dim strKeyContainer As String
    Dim hHash As Long
    Dim lRes As Long
    Dim lLen As Long
    Dim lIdx As Long
    Dim abData() As Byte

    strKeyContainer = App.EXEName

   ' Get default provider context handle
   lRes = CryptAcquireContext(hCtx, strKeyContainer, SERVICE_PROVIDER, PROV_RSA_FULL, 0)
   
   If lRes = 0 And Err.LastDllError = &H80090016 Then
      ' There's no default keyset!!!
      lRes = CryptAcquireContext(hCtx, strKeyContainer, SERVICE_PROVIDER, PROV_RSA_FULL, CRYPT_NEWKEYSET)
   End If

   If lRes <> 0 Then

      ' Create the hash
      lRes = CryptCreateHash(hCtx, Algorithm, 0, 0, hHash)

      If lRes <> 0 Then

         ' Hash the string
         lRes = CryptHashData(hHash, ByVal str, Len(str), 0)

         If lRes <> 0 Then
           
            ' Get the hash lenght
            lRes = CryptGetHashParam(hHash, HP_HASHSIZE, lLen, 4, 0)

            If lRes <> 0 Then

                ' Initialize the buffer
                ReDim abData(0 To lLen - 1)

                ' Get the hash value
                lRes = CryptGetHashParam(hHash, HP_HASHVAL, abData(0), lLen, 0)

                If lRes <> 0 Then

                    ' Convert value to hex string
                    For lIdx = 0 To UBound(abData)
                        HashString = HashString & _
                                     Right$("0" & Hex$(abData(lIdx)), 2)
                    Next

                End If

            End If

         End If

         ' Release the hash handle
         CryptDestroyHash hHash

      End If
     
   End If

   ' Release the provider context
   CryptReleaseContext hCtx, 0

   ' Raise an error if lRes = 0
   If lRes = 0 Then Err.Raise Err.LastDllError, "HashString()"

End Function
0

Featured Post

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

Join & Write a Comment

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

707 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

15 Experts available now in Live!

Get 1:1 Help Now