tags:

views:

127

answers:

6

Hello,

I'm working on C++ project that is supposed to run on both Win32 and Linux, the software is to be deployed to small computers, usually working in remote locations - each machine likely to contain it's own users/service-men pool.

Recently, our client has requested that we introduce access control via password protection.

We are to meet the following criteria :

  • Support remote login
  • Support remote password change
  • Support remote password reset EDITED
  • Support data retrieval on accidental/purposeful deletion
  • Support secure storage

I'm capable of meeting the "remote" requirements using an existing library, however what I do need to consider is a method of storing this data, preferably in a way that will work on both platforms and will not let the user see it/read it, encryption is not the issue here - it's the storage method itself.

Can anyone recommend a safe storage method that could help me meet those criteria?

EDIT

We're initially considering using a portable SQLite database, however what we are interested in, is limiting the access to the file with the data to users. How can we achieve that? (file not visible to the user, file cannot be opened manually by user etc.)

EDIT 2

Cheers for the responses flowing in so far, Can we focus on ways to limit the access to the file itself? Encryption is not the issue here. What we're looking for is a way to hide and or backup the file, and only permit the "MyApp.exe" to work with it.

So far we're also investigating Alternate NTFS Streams, however we're not sure if this will work on Linux

+3  A: 

Never store the password itself. Hash the password using a salt and store that.

sbi
That wasn't really my question
Maciek
I think it is an answer to your question, but maybe partialy. Always store hashed passwords. Of course you can't read it, and even computer can't read it (at least in reasonably short time). If your computer can read something, then human can also.
klew
+1 as sbi is perfectly correct, if you're really concerned about password security (and it isn't always so, sometimes storing the password itself is fine if the convenience outweighs the risk), then you you do need to use a salted hash.
Cruachan
@klew: Thanks for the correction!
sbi
+2  A: 

You could use a SQLite database. As it's just a file you can use standard file permissions to restrict access. e.g. chmod 600 foo.dbs will restrict access to the file so that only the owner can read/write to it.

Then as others have suggested you store a hashed password in the database and it'll be reasonably secure.

Rumour has it that there's a commercial version of SQLite available that encrypts the entire database file. However, this shouldn't be a substitute for storing hashed passwords, merely an addition to hashing.

edit: Here's the link to the commercial version of sqlite with support for encryption of the entire DB.

Glen
We are inclined to go this way, however we're need to restrict access to that file somewhow
Maciek
@Maciek, that's that file based permissions are for. My answer shows how to do this on Unix/Linux. For windows you'd have to ask someone who knows that better than i do
Glen
+2  A: 

I'm not quite sure if I fully understand your question. But anyway. How about setting up a user "FooUser" (assuming your product is "Foo"). Store the file / database at a location with read/write permitions only for user FooUser. Access file / database via service / daemon impersonating FooUser.

ur
That's one way to do it I suppose
Maciek
+1  A: 

First and foremost, neve store the plain-text password, instead store its hash. Using a salt is a good idea too if you expect the number of users to become large enough to have password collisions.

Do you actually need to store password on all of the systems, or can you get away with a centralized, password server, solution? If a server based solution is acceptable then a decent challenge response scheme can authenticate people without revealing their password or its hash. Secure communication witht the server using certificates, to make forgery harder and then just don't allow access to the password storage on the server, through whatever means is appropriate, which can be OS specific since there is only one, or just don't let people onto the server.

torak
We're dealing with a distributed system. Each machine having it's own pool of users/service-men
Maciek
+6  A: 

For logon you want to store an iterated salted hash of the password not the password itself. Two possibilities are:

  • bcrypt - A modified form of blowfish that increases the work factor
  • PBKDF2 - A function from the PKCS#5 spec that uses HMAC with a hash function and random salt to iterate over a password many times.

However, this will not work with your requirements:

  • Support remote password retrieval

I am hoping you can convince the client that what they really mean is to reset the password, in which case you can still use a password hash.

  • Support data retrieval on accidental/purposeful deletion

This requirementment is harder to work around and will require you to weaken security by storing encrypted passwords in the database so they can be reversed. To do this you should use a master key, encrypt each password with a random IV using a cipher like AES/CBC or AES/CTR mode. You should regularly rekey the master key and reencrypt all the passwords . You will then need a mechanism for working out when to allow password retrieval (e.g. mother's maiden name etc)

To use the password to encrypt data use the PKDF2 function from PKCS#5 to generate a key from the password.

Dean Povey
It's reset, not retrieval. Thanks for bringing that up
Maciek
A: 

I think the right way to go is:

  • in memory, you concatenate user name + password + some cookie (lets say: megan fox").

You then apply a commercial hash algorithm to it. I use SHA (System.Security.Cryptography.SHA1CryptoServiceProvider) from .NET Framework but I am sure it is no problem to make it work in C++ or perhaps get it for C++.

So, even if someone gets to look the stored hash, there is no way he can know the password. Event if he wants to compare identical passwords, he will get nothing because of the user name + cookie concatenation. Your login code must create the hash and compare it against the stored one

Problem is, you do not get to recover the password. But I think this is something good.

Hope this helps.

Daniel Dolz
This is not the answer to the question :)
Maciek
Ok, I guess you have to encrypt passwords using some good algorithm. Problem is, password must be somewhere in the code.I always think the main threats are employees that have access to the DB and hardware infraestructure, not external attackers.
Daniel Dolz