If i am not wrong, when you want to encrypt the content in the database you will use md5. I use that right now for passwords. But now i want to add encryption to all personal information, etc for enterprise clients. Below are my questions:
If I md5 everything, will php display everything the normal way, like without the md5?
When i allow editing of the content, i will have to display the info without the md5 and then add md5 upon submission, correct?
If someone gets access to the database, they will only see md5. But if they download it and then remove md5, wouldn't they see all the info?
As you can tell i am an amateur under pressure. Please correct me if i am wrong with my thinking of md5. If so, how can i encrypt the databases keeping in mind that info will be edited by users anytime.
Thanks.
MD5 is a hashing algorithm, not an encryption algorithm. Hashing is one way; that is, you cannot take hashed data and turn it back into the original data. MD5 is used to hash passwords (well, hashing algorithms are used to hash passwords...MD5 is generally regarded as insecure and not suitable for applications involving security...like passwords) because all you care about is whether or not the passwords match, not what the password actually is. This allows you to store a token in your database (the hash) that you can use to compare without actually storing the password.
If you're going to do application-level encryption of database data (rather than relying on any RDBMS-specific encryption features), you will always have to encrypt the data (in code) before you put it into the database and decrypt the data (in code) whenever you take it out of the database. For systems like this, a symmetric key encryption algorithm like AES is generally used.
MD5 is an hashing function! Is a one-way function.
You cannot decode a MD5 hash !
If you encode you content with MD5, you loose the data!!!
Instead use 3DES, BLOWFISH or other encryption methods!
Encription depends from DB to DB. More or less every db has an encription module to use (and pay)
As far as I know, MD5 is known not to really be a secure hashing function nowadays. There are places out there on the web offering reverse MD5 services, where they collect a huge database of strings with their MD5 equivalent. Try going for something like SHA-512 and use techniques like iterative hashing to make it more secure. PHP has a crypt() library you might like to checkout, or use SQLite database encryption maybe.
If I md5 everything, will php display everything the normal way, like without the md5?
Nope. Everything will be an md5 digest. The original data will be (almost) impossible to recover from the digest.
When i allow editing of the content, i will have to display the info without the md5 and then add md5 upon submission, correct?
Since the md5 digest cannot (easily) be decoded into the original data, you'll have to keep the original info somewhere.
If someone gets access to the database, they will only see md5. But if they download it and then remove md5, wouldn't they see all the info?
Nope. The md5 digest cannot (easily) be reversed to reconstruct any of the original info.
MD5 is one way hashing function. It won't be decrypted. JUST ENCRYPTED.
Related
I'm working on adding the option to encrypt uploaded files on my website by giving each file a "password", but I'm not sure of the best way to keep track of the encryption keys for each individual file. For example, when retrieving the file if the user enters the wrong password I'm pretty sure it'll download the file, but it won't be unencrypted properly. Is it best to store the hashed & salted passwords for each file in a database and match up there first? Or is there a better way to do it?
If you store the encryption keys as hashed (and salted) values, there is no way to retrieve the original encryption key. If you hash something (with a strong hashing algorithm), you cannot get the original back.
The best mechanism depends on the operating environment (OS, plus potentially other software installed), and on the requirements.
Depending on the specific requirements, it may be best not to store the encryption key at all. The point is that the user wants to protect data and the user knows the key. If it is possible to perform the encryption on the client side, the key would never have to traverse the network at all (e.g. encrypt in JavaScript). If the encryption must happen on the server, ensure the key is sent via an https connection, use it in memory to encrypt the file, and remove from memory (if your language supports immediately removing something from memory... e.g. in C# use a SecureString).
If you must keep the encryption key (which is a security issue on several levels), you will have to state more information about the operating environment.
I understand that passwords should be encrypted in databases to protect them from hackers and people with bad intentions. But MD5 was renewed in 2005. Since then, hackers found the inverse hash function and a lot of website can easily crack the MD5 hashed key, for example md5this.com which was one of the first suggested on google.
Shouldn't each web developper create their own hash functions so that the hackers can't retrieve the password if they get access to the database ?
You shouldn't use MD5 hash for that reason anymore.
It provides some security just not enough to matter.
Each web developer should, but they don't have the time usually so sha1 usually does the trick...
Sha1 is susceptible to a brute force attack, but it would be very time consuming for most developers to come up with their own encryption pattern that isn't susceptible to brute force attacks.
Is SHA-1 secure for password storage?
If you feel like you have the algorithmic chops to create a workable hash function please do so. The best advice I've seen to to switch from MD5 to the latest SHA implementation, use a salt, and think about running several loops of encryption to force extra work on any crackers.
Certain highly-sensitive information (payment info, usernames, passwords, etc.) should be encrypted before it can be persisted to my database.
Later, that information has to be decrypted in order to be fetched from persistence and used at a later time.
If I use, say, AES256 to encrypt a billing address, I'll still need to store that AES256 key/passphrase in persistence as well.
If the whole point behind encrypting information that is going into a database is to protect that information in case someone hacks into my database, and I'm storing the key to decrypt that same information in the database, then what's the point of encrypting the data in the first place?
If someone hacks into my database, they'll be able to find the persisted key and decrypt any encrypted data they want to anyways.
Am I missing something here?
There is an old saying "Encryption is easy, key management is hard". And that very much applies here.
If you need to store data in an encrypted format (you frequently don't because you only need to hash the data not encrypt it), you do not want the encryption key to be stored in the database. You want the key to be accessible when your applications need to decrypt the data but you don't want people like the DBA that has access to all the encrypted data to be able to get the key. You want to make sure that the key is backed up so that you can recover the data but you don't want those backups to comingle with your database backups. Key management, therefore, becomes a very thorny problem to solve.
In the vast majority of cases, you want to purchase some third-party key management solution that can deal with these contradictions. Just like you don't want to implement encryption algorithms on your own, you don't want to do key management on your own. The folks that attempt to solve key management on their own generally do not succeed.
A better option would be to use certificates and this can easily be done in most RDBMS.
The best option regarding passwords is to hash them. This is a one way hash, and is not decrypted. Basically, when a user logs in, you hash their input password, and compare the hash against the one stored in your db for a match - and a successful login.
Regarding payment information, you will need a random generated private key. Depending on the system and implementation this can be stored a number of different ways.
You can store this in a config file, encrypted using an RSA container for example so it is not readable.
There are other solutions as well.
You can also encrypted db connection strings and the like with the RSA container method above to help prevent anybody actually seeing you db username password your application will use to access the db.
I am currently working on a service which requires users to pick a 4-digit password/pin, because it is a mobile service. I am encrypting those passwords with either 256 or 2048bit encryption and it will be hashed. The account is blocked after 4 wrong entries, and can only be entered by mobile phone. Would it be hard to crack those PINs? I am asking this because sensitive information is being stored. The database is connected to a web application, the application is loaded to the phone using twilio. The thing I am most scared for is that the database is being hacked via the web. What would be a good way to keep sensitive data secure?
If someone gets hold of the database, you would be pretty much screwed:
If you just encrypt the 4-digit passwords, an attacker can just build a table of the 10000 possible encrypted strings and can trivially decrypt the PINs.
If you use salt strings (and encrypt not PIN, but PIN+salt and store crypted(PIN+salt) alongside with salt), people have to make a per-password effort, but there are still only 10000 possibilities for each password (which is not very much).
Which means, yes, by all means you should keep the database off the web. (If the web application is only ever accessed through twilio, you can reject connections from any other IP range).
Since you're using twilio, just make sure that twilo only talks to your web service using a secure protocol and reject any requests that you aren't sure are coming from a trusted source (that is, twilo). No real need for a pin at all.
This is a huge webpage on how to setup ssl between your web server and twilo. It even has a php example.
http://www.twilio.com/docs/security
If you use PKCS#1 1.5 or 2.0 RSA encryption (view the standards) you will also encrypt a random padding. This means that in transit, the PIN's cannot be compared, as long as the padding is kept secret and is truly random (this is not a salt which should be made public).
As for the database, it would be a good idea to move it out of the normal operations as much as possible. Create a simple service that just checks the PIN after decryption, make sure you don't have buffer overruns etc. on that, and if possible, use a different machine and access rights than the production server. Really test this part well, as the interface is small, it should not be difficult.
If you and the phones are up to it, you might want to try ECC, but that's not for the meek. RSA encrypt normally uses a small public exponent (0x010001 is highly recommended) so it is faster than ECC for the phone. On the server (and during key creation) ECC is much faster. I would not recommend symmetric cryptography (AES/3DES) for this.
Oh, and include the public encryption key in the application (for implicit trust), don't send it over from the server. Keep the private key secret and inaccessible for anything other than the already mentioned service.
The interface you describe sounds secure to me. It's secure enough for ATMs!
Are the encrypted PINs easy to crack? Yes, there's only 10000 possible combinations and a rainbow table can be generated of all the possible encrypted values unless you salt. However that would require access to the encrypted PINs which means the attacker already has a copy of your database.
So really you need to ensure your database server is secure. There's a lot of variables that could make it insecure so it's a big question. Instead you could rely on third-party solutions like Amazon S3 or others and concentrate on coding instead of security. Let them do the hard work!
You should use good quality password salting technique to prevent against hacking passwords. Check the wikipedia article to know more about salting. Salt Article
I've seen a few other threads about this topic, but I can't seem to find a few answers to some questions involving the use of a random salt in password encryption. To my understanding, the steps go something like this:
Generate a random salt for the user.
Append the salt to their password.
Use something like SHA-2 to hash the result.
Store both the salt and hashed password in the database.
How does this method work when retrieving the user's password and verifying log-in? One response says that the user's salt should be retrieved, appended to their inputted password, hashed, and then compared to the stored hash, but doesn't this raise some issues? Namely:
How do you retrieve the salt without compromising that user? If someone wanted to brute-force a certain account's password, wouldn't they be able to retrieve the salt that was sent back from the server to hash the inputted password, thereby eliminating the security that having a salt adds?
If we avoid the previous problem by doing the salt retrieval server-side, then won't we be sending the user's inputted password unencrypted at one point or another (so that it may later be appended to the retrieved salt)?
The salt should never be exposed outside of the service - your instinct is right that this would be exposing the salt and introducing risk.
Any communication between your client and server should occur over an SSL connection - or at least using some kind of encryption of the interaction.
Keep in mind the purpose of the salt: to make it harder for someone to precalculate hash codes and therefore be able to look up passwords in the case of the database being compromised. An 8 bit salt makes the hash space 256 times bigger, making precalculation that much harder. The salt isn't about securing communication - there are other solutions for that.
You have to use random salt because of goal of using it is protecting against some types of attacks such as dictionary attack, brute-force attack and rainbow attack. thus it's so important to generate random salt for each password and store hashed password and salt in user table or attached to user profile. When you want to validate user password it's enough to hash entered password with stored salt and compare with stored hash value. I don't believe #cherouvim advise because it seems he doesn't care about above attacks. For more information i suggest an amazing, simple and understandable article by Defuse Security
Good luck.
I use a fixed salt (for all passwords) which is hardcoded on the application code. Assuming that the salt cannot be exposed (e.g via the UI of the application) this looks simple and good enough.
The only way to not send an unencrypted value which can be used to log in is to use SSL. If the hash gets sent to the server, the hash itself can be sniffed and used to log in. Do it server side.
+1 to what ruslik said about the salt. It prevents dictionary/rainbow attacks. A rainbow table for an average password + several bytes of random binary data would be astronomically huge.
Security introduced by salt is that you obtain hash for something much bigger and non-standard than the plain password. It doesn't matter if its algorithm is closed, because it protects the hash stored in plain in database from rainbow or dictionary attacks.
It's also reccomended to take hash several times recursively, maybe readding the salt at each iterations, so that brute force will take much longer.
EDIT: to what Bevan said about communication: usually the "number used once" (NONCE) scheme is used to transmit passwords over unsecure channels. The server gives a random string never used before to the client, he appends it to the plain password, computes hash, and sends it. This protects you from eavesdropping attacks.
Hashing passwords protects against plainly visible passwords, and salting them guards against dictionary attacks. As far as protecting passwords during transport, I would recommend SSL/TLS.