Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

Background: I have little knowledge of hashing and encryption, so please bear with me. I have posted a related question here: http://programmers.stackexchange.com/questions/232261/options-for-client-side-encryption-of-local-web-databases for the programming perspective, which may give some background. That question was about the general feasibility of the overall product. In a sense, this question is a follow-up, about the actual implementation, but as it is more technical on the security side I felt it would be better posted here. Feel free to post on either question/both questions as appropriate.

I have been tasked in securing local data for a web application that can be used offline, so interaction with the server for authentication and encryption is not an option. This would be optional, for users who would like an extra layer of protection on top of the hardware encryption.

The application will be for a single user per device. The goal is to try and reduce the risk of unauthorised access to sensitive data if a device is lost or stolen.

My initial ideas of how I could do this are:

  • Require the user to enter a password every time the application starts.
  • Hash the password using PBKDF2, storing the hash and the salt locally, e.g. in WebSQL.
  • User would then enter their password, it could be re-hashed using the loaded salt and compared against the stored hash.
  • Store the password in a JavaScript variable locally, perhaps using a different hashing method to what is used to store in the database?
  • Use this as a key for encrypting and decrypting (using AES) data in the database.

The local data will be encrypted - however the encryption/decryption logic will be evident from looking at the JavaScript source code. So the key used to encrypt/decrypt cannot just be the stored, hashed password, as that would be obvious.

Q: How could this approach be improved? Would hashing the password in two different ways, one for storage, and one for encryption/decryption, be sufficient? Is there anything more that I could be doing, bearing in mind the limitations of working with web storage and without a server/external hardware to assist?

Also - although the user will be working offline with the application, so the data needs to be local and encrypted, there will be an initial connection to the server to actually download the application. So if there is anything I can do based on that initial connection that might help then let me know.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

You are going about it wrong. There is no point at all to a hash for authentication if the comparisons are being done locally because an attacker can simply inject the hash value directly into memory and bypass the authentication check.

For local purposes, you have to use something like your second part of your idea, but that part should be done using existing standards. What you need is a key derivation function. A key derivation function is an algorithm that can securely take a password and use it to form an encryption key. Since the keys that are built are frequently relatively weak, it should be used to encrypt a truly random key which is then used for the actual encryption and decryption of the DB.

Using an encryption based approach, it becomes irrelevant if the user forces a key in to memory because they will be unable to access the encrypted data. The encryption itself acts as both the authentication and data protection mechanism. (If you want a way to verify proper decryption, you can always encrypt a known value and check the decryption of that value.)

share|improve this answer
    
Thank you. I get the first point completely. The scenario would then be though, that they can bypass the login, but they can't decrypt the data because they haven't provided the password. At the moment, I don't understand what you mean about the encryption acting as authentication as well - practically. User enters password - a key is derived from it, and this is then used for encryption/decryption, but how can we verify that the password is correct? –  Adam Marshall Mar 18 at 13:53
1  
@AdamMarshall - you can store a known value encrypted. So when I first enter my password, the application stores the value. "I am me" in the DB. When I enter my password to authenticate, the key is derived, the encrypted value is decrypted and the code checks to see if it says "I am me". If it is, then I entered the correct password, if not, I entered an incorrect password. –  AJ Henderson Mar 18 at 13:57
    
Aha. OK. I think I'm there! Great. Do you think that would be sufficient? –  Adam Marshall Mar 18 at 13:59
    
That is in fact the preferred and pretty much only way to secure a local application since all operations and unencrypted data are inherently untrusted. The entire basis of trust is in the user holding the secret and trusting the computer when they use it. Trusted computing when available offers a little more protection but is far more complex and not particularly widely available. –  AJ Henderson Mar 18 at 14:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.