Q:

VB - hashing registration data for offline authorization

I have a vb application where I was using an online mysql database for user access.  The online database had username, password, then a bunch of single digit (basically yes/no) fields for determining which items that user was allowed to access.  When a user would log in, the database retrieved all the 'yes' answers and enabled those buttons, and retrieved all the 'no' answers and disabled those buttons.
My issue is there is a very good possibility that any given user will not be online.  So I thought of copying the online database to a local device (this program is going to be running on windows tablets that may or may not have internet - possibly never having internet connection).  This would suffice except a user may use a different tablet and that device wouldn't know what the user is allowed to access (based on a lack of internet connection).
So my new approach is when a user registers, having them provide first name, last name, phone number, and email address.  At this point in time I would also select which buttons they are authorized to use.  I want to put all that info into a code (probably a hash) so the next time the user would login (online or offline), they would use their first name, last name, and the generated code.  The user could even go to a different device and still get the same result.  I hope this makes sense.
So basically I am looking for a way (I am pretty sure hashing is involved) that would allow a user to register with some info, receive a code that ties it together, then log on to any windows tablet that is running my program without the device ever having to go online to download a new list of authorized users.
Thanks in advance.

A:

A hash is part of what you're thinking of, but not the whole thing. A key part of a hash is that it's not reversible, and so you can't use a hash on it's own to communicate information like which buttons to enable/disable.  It does sound like you also need to implement hashing elsewhere in your system (NEVER store unhashed passwords!). The rest of what you need for this question are secure check digits.  
The idea is that you generate a number with a few holes/empty spaces, where different parts of the number have different meaning. It might look something like:

4325_-23R3_-F257_-D982_-__

A few of those characters are a hash of the user information, with the bits from other characters corresponding to your Yes/No database fields.  Once you have this much, you have an algorithm (using a secure key) that computes what characters belong in the missing spaces, and then you can issue the final number to your user.  Your software will take the number entered by the user, and check to the make sure the check digits it comes up with match the check digits entered.
There is a downside to this approach. Allowing offline activation means including including the key used to compute the check digits with your product, and as with any digital security once you put that kind of thing out in the wild crackers will be able to find a way to get at it.

Now let's move on to the big gaping security hole in your current code. You state that your database stores a username and password. I'm hoping that you're just simplifying things, but this is a huge problem, to that point that I can't in conscience leave it unchallenged. Instead of storing the actual password, you should hash the password and store only the hash.  When someone wants to log in, you hash the attempted password they try to use and compare the hashes.  This is a big deal, and if you're not doing that, you're doing it wrong.  
That also over-simplifies it a bit. You also want to salt your passwords before hashing them, to help thwart dictionary attacks on common hash results.  Additionally, choice of hashing algorithm matters. md5 does not cut it here.  Your best option is bcrypt or scrypt, but you can use sha1 for now if you really have to.
The biggest thing to know here is that you should never try to build your own authentication system. It's easy to get it close enough that it passes all your tests, but is still wrong in some subtle way that won't know about until a year later when you find out you were hacked six months ago.  Instead, look for a pre-written component or product for your existing platform to handle this. Rely as much as possible on code from projects (and programmers) that specialize in this area.

