Best way to encrypt and decrypt data using php and mysql - algorithm

To start, I am trying to encrypt very sensitive information on a public website. Users will be able to update their information, Administrators will need access to this information. I am worried that if the encrypted data is some how compromised, then everyone's information would be as well due to them all using the same salt and key.
So I know using a salt, and key is always preferred. But as mentioned above if they reverse engineer the encrypted data, what use it is.
My solution, is to have the key and salt stored in a DB, with many rows and columns, any of which can be used for the salt or key. I would have an algorithm that will use "something" fixed in the users account that will be used to figure out which salt and key to use. This way statistically speaking no 2 years will have same combo of salt and key.
Is this over kill, or good?

I question the value of this second database that holds keys and salts. Consider:
The "something" in the user's data that identifies the salt and key will necessarily have to be encrypted differently from the rest of the user's data. Otherwise, you wouldn't be able to get it without first already having it.
Statistical analysis of the encrypted user data would almost certainly discover that the "something" is encrypted differently. That will be like waving a red flag at a bull, and an attacker will concentrate on figuring out why that's different.
You can assume that if an attacker can get the database of encrypted user information, he can also get the database of salts and keys.
Given that, there are two possible scenarios:
The encryption of the "something" that identifies the key and salt is unbreakable. That is, it's so good that the attacker's best efforts fail to reveal the connection between that "something" and the key/salt database.
The attacker discovers the encryption of the "something," and therefore is able to decrypt your sensitive data.
If #1 is the case, then you probably should use that encryption algorithm for all of your user data. Why do something in two steps when you can do it just as effectively in one?
If #2 is the case, then all the work you've done just put up a little bump in the road for the attacker.
So, short answer: what you propose looks like either unnecessary work or ineffective road blocking. In either case, it looks to me like a whole lot of work and added complexity for no appreciable gain.
That said, I could have misinterpreted your brief description. If so, please correct me.

Related

Can databases encrypted with Laravel or any other encryption method be decrypted?

everyone. I'm learning Laravel and I'm in the start of my journey. I was learning about encryption and decryption in Laravel today and then this thought came into my mind. Could be a stupid one but I want to know my answers.
Let's say I make a database which stores sensitive information about users and I encrypt all the data before storing into the database, let's just say using the Encrypt class of Laravel. Now my questions:
If someone steals that database and luckily finds out that this information was encrypted using techniques provided by Laravel or any other technique. Can't that person descript that all data using the same decryption technique that was used to encrypt it. If this can be done, then what's the point of doing this encryption?
If that can be done then how can we make sure that our data is actually encrypted and is safe even if someone steals it?
Thank you guys!
I encrypted my data and then decrypted it and want my answer that how that encrypted data is even safe.
You might want to read up on the basics of encryption.
The common approach is that the technique by which you encrypt should be as open as possible - because the more people look at the algorithm, the less likely there might be bugs.
However, even if the algorithm is public, the key is not. Only people who have the key can decrypt properly encrypted data. This is true of the AES algorithm Laravel uses too.
The mathematics are complicated, but essentially the length of the key determines the amount of computer resources required to break the encryption.
THe real-world example is that everyone knows how door locks work. There are millions of locks that all work in the same way - but only people who have a key can open the door.
So, if an attacker steals your database, they cannot read your content unless they also have the key, as long as the key length is sufficient.
If someone steals that database and luckily finds out that this information was encrypted using techniques provided by Laravel or any other technique. Can't that person descript that all data using the same decryption technique that was used to encrypt it. If this can be done, then what's the point of doing this encryption?
If someone steals that database they will still need a decryption key to decrypt (thats why strong passwords are recommended) so even if they bruteforce it will become almost impossible to decrypt.
The way you’re asking if encrypt and decrypt is easy then i think you’re asking some encryption like base64.
With AES bruteforcing their way in becomes difficult. In laravel encrypt or crypt class it uses AES-256-CBC which is pretty good at that.
Then there is Hash library they are one way encryption techniques which uses bcrypt it can only be verified and not decrypt you have to run all combinations for lines everytime to brute force. Unlike md5 which gives same encryted string every time.

why windows hashes a password?

There are many operating system and programs that hash passwords for authentication.
Even though they can encrypt the password in many different ways and save it
why do they save the hash of them?
Is the only reason to that question that encrypting them may cause in breaking and decrypting them or there are other reasons?
Thanks for answering in advance
User credentials (≈passwords) are among the most valuable assets stored in an application. They are a prime target for attackers, and as a developer, you want to protect them the best you can.
The principle of defense in depth (and common sense) indicates that the more layers of protection you can put around something, the more secure it will be. So as you also mentioned, the purpose of hashing passwords is that even if there is a breach, an attacker still can't get hold of actual user credentials.
The problem with encryption is always key management. If passwords were stored encrypted, they would need to be decrypted (or the received password encrypted with the same key) to be able to verify a password. For this, the application would need to have access to the key. But that negates the purpose of encryption, an attacker would also have access to the key in case of a breach. (Public key cryptography could make it somewhat more difficult, but essentially the same problem of key management would still persist.)
So in short, only storing salted hashes with an algorithm that is slow enough to prevent brute-force attacks (like PBKDF2 or Bcrypt) is both the simplest and the most secure. (Also note that plain salted hashes are not good enough anymore.)
Think of the need: You define your new password, and then every time you log-in the entered password is hashed and checked against the stored value. This is the simplest and most secure policy to handle this (since no one will be able to re-construct your password from the stored value). Moreover, imagine that you use the same password in several systems. If Windows would enable (regardless how hard it would be) to re-construct your password from what is stored in a Windows system, there would be (quite many) people that would blame Microsoft for security breach on other system (which could derivate into legal actions).
To summarize, simplicity and commercially logical approach.
Well, actually it's for security reason.
Hash functions are usually not revertibles, so even if someone finds out the hashes it would be really difficult for him to find which password generated that hash value.
Obviously you can try with a dictionary attack or a brute force one, trying to find out the password which generated the hash but it could take a very long time.
Consider that you have a Database with user and their passowrd, take note that a lot of people use the very same password everywhere.
Now immagine if a cracker manages to crack into your DB and finds all the password written clearly. That would be a disaster.

Verify validity of a key without weakening of the chipher strength

I have a very large block of code (few seconds to crypt).
I use KeyA to encrypt it.
later in the process, i receive a key (not necessarily KeyA)...
but i don't need to open the block yet,
what i really need, is to validate that this is really the Key that will open the code correctly.
I Assumed i can keep a known block, and encrypt it,
and in order to validate the key, only open it, but it feels like weakenning the power of the cryptography (brute-force is easier, one can learn few things about the key properties).
Does my assumption really weakening the chipher? why yes/why no?
Is there a different way to ensure the match of a key without opening the whole block.
I am assuming you are using Symmetric-Key Cryptography (the kind where the key used to decrypt the file is the same as the one used to encrypt it).
If the cipher is vulnerable to a Known-Plaintext Attack, then the known block of plaintext may reveal information about the key. The stream cipher used for ZIP files suffered from this problem. Because ZIPs are compressed, it was difficult to guess enough plain-text, but the checksum used to verify passwords (among other factors) helped provide sufficient plain-text for a practical attack.
In principle you could publicize the hash of KeyA (assuming that the hash algorithm is strong enough that it cannot be reversed, and that the hash algorithm isn't also used internally by the cipher). This would allow you to quickly reject invalid keys without changing the way the message is encrypted.
Taking this idea further, you could use a Message authentication code such as HMAC. A message authentication code will validate that the message (in this case your very large block of code, or perhaps just its file path) has not been tampered with, as well as validating that the key is correct.
If you are concerned that this will make brute force easier or expose properties of the key, you could split the key into two parts. The first part of the key could be purely for validation, and the second part purely for decryption. e.g. MyKey = AuthenticationPart,DecryptionPart
(Disclaimer: This is based on my very incomplete understanding of crypto. You might get better responses from the experts on security.stackexchange.com and/or crypto.stackexchange.com)

Is using the Keychain inherently insecure (when getting items back?)

SecOps people disclaimer: I'm an informed amateur at this stuff. It's possible I'm misunderstanding something. If so, please advise :)
I'm doing some work with the Keychain/KeychainItemWrapper in my app. I want to store a user's password in a secure manner, and the Keychain seems like the way to do it.
However, I'm a little confused. I thought basic password security (modelled after unix crypt()) went something like this:
Encrypt and store user specified password, using an encryption algorithm that will give the same results every time (given the same salt)
At a later date, when the user enters their password, encrypt that too
Compare the two encrypted strings. Are they equal? The passwords must be the same
However, it appears that using KeychainItemWrapper (and maybe the entire Keychain API?) is meant towards giving the password as plain text back to the program. However, isn't that insecure? The unencrypted password is just sitting around in memory, waiting for someone to read it, right?
The question: What is the best pattern for storing passwords in Keychain, given my above worries about security and the fact that my program does not actually need to know the encrypted value? Or are my fears unfounded and I should stop worrying and learn to love the (unencrypted) password Keychain gives me?
You're confusing two concepts (hashing vs encryption).
When you need to verify that someone knows a password, you hash it (w/ salt) and store that hash. Then, when someone tries to authenticate as that user, you ask them for the password, hash it with the same salt, and compare with the stored value. This is ideal as hashing is a one-way/non-reversible function. So, if someone accesses your credential store, they gain nothing as they would need to crack that hash (and modern algorithms like crypt/bcrypt are specifically designed to make brute force cracking very difficult).
However, if you need to be able to actually recover the plaintext password, you will encrypt the password instead of hashing it. Unlike cryptographic hashing, encryption is reversible, assuming you know the key.
The Keychain encrypts whatever you store in it with the assumption that you'll need to recover the actual data at some point (for example, if I put my Facebook password in a Keychain, it would be able to decrypt it and supply the actual password, when I need to use it to access Facebook). Keychain is designed to store those secret values encrypted, so that when you need to actually recover the original value you can.

Client Side MD5 Hash with Time Salt

I want to salt a hashed username and password (submitted via http POST) in JS on the client-side with a higher-order time value (< 1 minute resolution) to avoid sending the username and password hash as a constant value that could be used for a log-in attempt via POST fabrication by an unauthorized user (i.e. a sniffer).
This will impose a short expiry on the usefulness of the passed hash.
If they inspect the JS and see that it uses this time salt, how much easier will it make the job of breaking the MD5 if they know what the salt is?
Stephen
The salt doesn't need to be secret. In that sense, your solution is okay.
MD5 is broken in some applications; this one might be alright, but why not use a hash from the SHA-2 family? For that matter, why not use SSL to provide a confidential channel, and better security?
The time-based salt will not make MD5 any easier to break. You're still relying on 1) the user having a good password to defeat brute force calculations, and 2) MD5 being a decent hash. That's the basic answer to your question. However, this may not be a good idea anyway. Some comments--
Unless you can ensure the client or server's time are synchronized (or you use Javascript to fake a synchronization), the client would have to send the time it used as salt. The server would have to decide if the time used was close enough to the server's time.
Even if synchronized, you'd probably have to accept hashes plus or minus a minute or so because of latency on the Internet. Another problem is that if I'm sniffing I could immediately reuse this hash as long as I'm still within this time window.
Because of the problems above a better idea is to use a one-time server-assigned salt with the hash since it sounds like you don't want to use SSL. In other words, everytime a login form is sent to the client, the server would generate a random, unique salt string, sending it to the client and keep track that this is an acceptable salt. Then the client uses that as salt with the password. After this is submitted once, the server discards this as an acceptable salt string. No two hashes should ever be the same. The downside of this is you have to keep track of these acceptable salt strings.
Their job will become infeasible, since you can't use a rainbow table at all if the hash is salted correctly, and you can't break MD5 in less than a minute, by which time the hash is invalidated anyway.
you could use code obfuscation to make the salt harder to find

Resources