RC4 Encryption with Access/VBA

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • BHo15
    New Member
    • Feb 2014
    • 143

    RC4 Encryption with Access/VBA

    This is a question for all, but Rabbit... I read your article on RC4 ("RC4 Encryption Algorithm for VBA and VBScript"), and have used it in a DB. It works great, but of course all I am doing is obfuscating the data instead of actually encrypting (because the key is kept in the database).

    Do you know of a way to hide the key when using RC4 in a typical Access DB?

    Thanks,
    Brad
  • Rabbit
    Recognized Expert MVP
    • Jan 2007
    • 12517

    #2
    You use a password entry form to let the users that have access to that particular data enter the password.

    If your goal is to allow anyone who has legitimate access to the database see all the data, then you don't really need to use the encryption functions in my articles. You can just use the built in full file encryption that comes with Access. It's quicker and encrypts everything instead of just the data.

    Where my encryption code would come in is when you want some users to have access to some of the data. In this scenario, you encrypt the confidential data with a password only they know and you use a form to let them enter the password for encryption / decryption. The form would compare the password hash to the hash of their entry to make sure they entered the correct password without storing the actual password.

    Comment

    • BHo15
      New Member
      • Feb 2014
      • 143

      #3
      Actually, what I am using the RC4 for is to encrypt the table containing user passwords to enter the database. The RC4 function is used encrypt the password they choose, and then used to decrypt it to check it against what the PW they enter upon opening the DB.

      So the encryption is working great, but the RC4 function requires a key, and I just can't figure out a way to hide the key being used (key management).

      Thanks.

      Comment

      • Rabbit
        Recognized Expert MVP
        • Jan 2007
        • 12517

        #4
        You don't encrypt passwords for storage. Instead, you hash the passwords and store the hash. Hashes don't require a password to use and are one way only, meaning you can't take the hash and retrieve the original value. Which is fine for passwords because you don't need the original password, you only need to compare if two hashes are the same.

        Comment

        • NeoPa
          Recognized Expert Moderator MVP
          • Oct 2006
          • 32633

          #5
          While that may take a bit of getting one's head around, it is solid advice. Few understand security as well as Rabbit.

          From the few posts you've added it seems clear you're reasonably bright and capable. I expect you'll understand what Rabbit's saying better than most. Feel free to question further if required but I suspect you have all you need. Let us know how you get on.

          Comment

          • BHo15
            New Member
            • Feb 2014
            • 143

            #6
            The hash makes all the sense in the world. Believe it or not... I've got a CISSP, but am just beginning to learn how every thing fits together in the real world. :)

            What data type should I be using in the table to store the hash? I tried Long Text, and got a Type Mismatch when trying to run my update command.

            Comment

            • Rabbit
              Recognized Expert MVP
              • Jan 2007
              • 12517

              #7
              The hash result comes as an array of integers. It's up to you how you want to store that. Some people convert the array into an ASCII string while others convert it to a string of hex values.

              Comment

              • BHo15
                New Member
                • Feb 2014
                • 143

                #8
                Arrays have always been my weak spot (unfortunate, isn't it?). I would assume that I would need to parse out the array values by the commas?, and then use a function to convert it all to an ASCII string?

                I would like to know how to do this, but I did find another solution. It appears to do what I want it to, and also appears to be fairly secure. Here is the code for resetting a password...

                Code:
                Private Sub txtPW_AfterUpdate()
                    DoCmd.SetWarnings False
                    DoCmd.RunSQL "UPDATE tblPWs SET tblPWs.PW = '" & Hash(Forms!frmTest.txtPW) & "'"
                    DoCmd.SetWarnings True
                End Sub

                Comment

                • BHo15
                  New Member
                  • Feb 2014
                  • 143

                  #9
                  Sorry... Left out the module for the Hash. Here it is.

                  Code:
                  'From http://www.freevbcode.com/ShowCode.asp?ID=972
                  
                  Public Function Hash(ByVal text As String) As String
                      a = 1
                      For i = 1 To Len(text)
                          a = Sqr(a * i * Asc(Mid(text, i, 1))) 'Numeric Hash
                      Next i
                      Rnd (-1)
                      Randomize a 'seed PRNG
                      For i = 1 To 16
                          Hash = Hash & Chr(Int(Rnd * 256))
                      Next i
                  End Function

                  Comment

                  • Rabbit
                    Recognized Expert MVP
                    • Jan 2007
                    • 12517

                    #10
                    There are no commas in an array, it's distinct elements. You loop through each element and concatenate the values into one string.

                    I would be careful with that hashing algorithm you found. It's unlikely to be considered a cryptographical ly secure algorithm. Meaning it's likely to have weaknesses that can be exploited to find the original values.

                    Comment

                    • BHo15
                      New Member
                      • Feb 2014
                      • 143

                      #11
                      So, I'm getting a little closer. If I loop through the array to get all of the values and put them into a string (such as below)...
                      Code:
                          For x = LBound(arrHash) To UBound(arrHash)
                              strArr = strArr + CStr(arrHash(x))
                          Next x
                      ... I would begin with an array such as this - 231, 207, 62, 244, 241, 124, 57, 153, 169, 79, 44, 111, 97, 46, 138, 136, 142, 91, 16, 38, 135, 142, 78, 25, 57, 139, 35, 189, 56, 236, 34, 26, and end up with a string such as this - 231207622442411 245715316979441 119746138136142 911638135142782 557139351895623 63426.

                      What am I missing?

                      Thanks for the patience.
                      Brad

                      Comment

                      • Rabbit
                        Recognized Expert MVP
                        • Jan 2007
                        • 12517

                        #12
                        That depends on if you want to store it as a hex string to make it more human readable or a regular string. The easiest would be to store it as a regular string in which case you use the CHR() function to convert the integer to a character before you append it to the string.

                        Comment

                        • BHo15
                          New Member
                          • Feb 2014
                          • 143

                          #13
                          BEAUTIFUL!!!

                          That's what I needed. That gets me a nice obscure string to append to the table.

                          Thanks ever so much for the help (and even for making me dig a bit... you know - it helps with the learning :)

                          Comment

                          • Rabbit
                            Recognized Expert MVP
                            • Jan 2007
                            • 12517

                            #14
                            No problem, good luck with the rest of your project.

                            I'm glad you like my style of guidance. I prefer to give small hints in the hopes that working through the problem will provide more knowledge in the long run.

                            Here are a couple of other things you can do to improve the security of your username/password table.

                            1) Hash the username. Because Access doesn't have a way to prevent users from accessing the table, a user can potentially mess with the table if they know which row belongs to which user.

                            2) Incorporate a salt into the hash. Because some people can use the same password as another user, the hash will come out the same. To prevent the same hash for the same password, it is recommended that you supply a "salt" or "initializa tion vector" to the hash. Basically, what you are doing here is supplying a known value that is used to modify the pre-hash string before hashing, this results in a different hash even if you are hashing the same value. One common way of doing this is using a unique id to xor each byte of the pre-hash value.

                            Comment

                            • BHo15
                              New Member
                              • Feb 2014
                              • 143

                              #15
                              Salting is a good idea. I understand what it is, but don't know how to use it. If I salt, how do I make sure that I get the same thing every time the user enters the DB? I saw something on the web about storing the salt and the hashes separately, but that doesn't make any sense to me.

                              Thoughts?

                              Comment

                              Working...