We have a requirement from customer that if someone gets access to the database, all data that includes personal information should be encrypted, so that when they do select calls, they shouldn't be able to see anything in clear text. Now this isn't any problem for Strings, but what about bytearrays? (that can potentially be quite huge (several 100mb))
When you do a select call, you get gibberish anyways. Is it possible for a hacker to somehow read the bytes and get the sensitive information without knowing how the structure of the object it is mapped against is?
Because if that is the case, then I guess we should encrypt those bytes, even if they can potentially be quite huge. (I am guessing adding encryption will make them even bigger)
This seems to be an approach that will give you little additional security for a large amount of effort, not to mention the extra headaches of debugging queries using encrypted data!
If protecting the data in the database is the goal, I recommend encrypting the database as a whole, and using authentication and access control to ensure data is provided only to your program and no unauthorized access. If the database falls into wrong hands, under this system, the evil scoundrels will have to figure out the username/password or other credentials use to authenticate a legitimate user to gain access. Typically this means either a brute force search, or reverse engineering your code (if the credentials are stored in your program - not such a good idea.)
If you encrypt all the data in the database on a row-by-row level, so that it comes to your program encrypted, it must still be decrypted by your program. The secret key can be found by reverse engineering your code.
So, I hope you see, encrypting each returned result set will be complex to implement, yet is no more secure than using readily available solutions (database file encryption and authentication/access control).
EDIT: I've written this with a local database in mind, since the OP talks about the attacker getting hold of the database. On the other hand, if you are using a remote database server, which is physically secure, a protocol with transport layer encryption, e.g. HTTPS will give you what you want. An attacker in the middle will not be able to make any sense of the data going between your program and the database. It's also transparent - your data access code does not need to change at all.
First of all, encryption won't normally increase size, except possibly to the next multiple of the encryption algorithm's block size (e.g., 128 bit boundary).
Second, yes, if the data is left in the clear, an attacker can probably make sense of at least quite a bit of it fairly quickly.
Third, the big problem with all of this (as with most cryptology) is key storage and distribution. At some point you have to decrypt the data, and (often) the easiest form of attack is to find a way to retrieve that key. Your two main choices are to require the user to enter a key, or to have some sort of protected storage (e.g., a smart card) to store the key, and use smartcard readers on the client computers.
Depending on the database you're using, it may be able to handle a lot of this for you. A fair number have some sort of row-level or even column-level encryption to help comply with privacy requirements (e.g. Sarbanes-Oxley in the US).
Related
I've been learning about ways to keep databases for web applications more secure in School and one of the things mentioned was the encryption of data of the user's personal information. Now when I'm looking through examples of web systems I've noticed that it's normally just the password that is hashed, for obvious reasons, but should there be some sort of encryption when it comes storing a user's details such as their address? Is it safe to have these stored in plain text as long as you have measures in place to keep your database secure or should this be encrypted?
Sorry if this is the wrong place to ask but thought I would be able to get a good answer here
Yes, any Personally Identifiable Information (PII) should be encrypted in transit and at rest because it may be used for identity theft. There are recent instances of hackers getting into systems and stealing data that is then potentially sold on eg the Travelex data breach https://www.bbc.co.uk/news/business-51017852. Encrypting the data makes it valueless even if hackers do get into your network.
This is different to password hashing which is a one way mechanism to allow comparison of provided credentials against stored credentials without ever needing to convert the stored value to plaintext. PII data does normally need to be decrypted by the applications that use it.
The first & accepted answer on this question about passwords management suggests to encrypt the user identifiers in DB.
The good point is that if anyone gets a password, he has to know how to decrypt the user login to get the full login/password pair.
Some disadvantages I see, for example:
you have to decrypt user logins every time you want to display them
if you want to do a 'begins with' search on user login to find users, you cannot simply use LIKE '...%'
ORDER BY on login field may be quite difficult too...
What would you recommend (encrypt user identifiers or not)?
As usual, the answer is "it depends".
In general, I'd say that if an attacker has access to your database, your security situation is so badly compromised that encrypting the passwords will likely do you no favours. This is different to using a one-way hash - it's likely that an attacker who has access to your database also has access to your decryption key, whereas one-way hashes, by definition, are one way.
As you already say, it's likely that you will need regular access to the userIDs (esp. if you use email addresses as user IDs); in that case, again, an attacker who can read your database likely can intercept the unencrypted data.
So, if you work for a bank, the government, or any other place where data security has to be at the very top of the list, this additional protection may just be worth it, especially if you have a strong key management system.
For other uses, I'd consider the additional security too small to merit the additional pain.
Encryption is considered to be a lesser form of secret storage than message digest functions. In fact, storing an encrypted password is a clear violation of CWE-257.
But why not hash the username? When the login the application will have the plain text. Depending on your application, you might not need to display a list of users. this would be an added layer of security, as both hashes have to be broken before the attacker can login.
That being said, if you have a plain text list of every username it will be trivial to perform a dictionary attack against any recovered hash. Further more user names are not created to be difficult to guess, often times users choose goofy names of birds or silly games like chess so that they are easy to remember.
Is there a way to design a database where users' profile data can be protected in case of system intrusion?
For example, private data may be valuable, even though it may not be directly related to financial transactions or passwords. [Phone numbers, email addresses, etc may be resold]
Is there a way to design a member-based website in which personal information is stored and manipulated by an authorized agent of the site. However, in this case the data could become devalued if the database was disconnected from the system.
I realize that most of user privacy and data concerns are mostly focused on the UI and preventing unauthorized users from accessing data that does not concern them. However, my question is how can user information be protected within the backend itself. I also realize that this is a case of loss of access of the data [and you can do anything reactive (technical wise)], but what I'm trying to discover is if something can be done proactively to dampen the blow.
My question is: how can personal data be protected, without taking away from the actual purpose of the data?
I can see a need for encrypting all information, but that would prevent groups from accessing the data related to the user. For example, you could encrypt userss zip codes with a private key, but how would you retain the ability to use the zip code's location information. [Maybe to make a claim to the user "these people may be near you"]
In this hypothetical situation, the attacker is given an exploited database. They can not use the originating system to manipulate the DB.
If you only access the users' information when they are logged in, you can use their password to decrypt data from the database. During this time, you could calculate a one-way hash from the zip code, for example, and store that unecrypted. But if you develop your database during the site's lifetime, you won't be able to update the information for old users who never log in. Maybe that isn't a problem in practice.
I'm going to presume that you're indicating an intruder has gained not only access to the machine, but any MySQL passwords as well.
With that being the case, the only solution I can think of would be to use an encrypted filesystem underneath the database.
Even there, though, you've still lost physical control of the device - so if the intruder has figured out the decryption key for the fs, you're still up the proverbial creek.
Another option would be to split the application so that the web site and database do not share the same system. And, of course, typically running the site with a read-only user is a Good Idea™ :)
Storing data in the database in a hashed or encrypted form is a good start, but you still need to have access to the decryption key, or it's going to be gobbledygook.
Ultimately, of course, the best way to secure the database is to prevent access - which is not a viable solution.
This is an issue that appears in the press periodically if/when a bank or store's customer list is accessed in an unauthorized form - the data is secure only via the interface/application: it's still in cleartext at some point underneath everything else.
Proper access controls are probably the most sensible approach in your example since you're not wanting to give up, e.g., the ability to sort or query against the fields in question.
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'm looking for a stornger scheme than just password salting-and-hashing.
I want passwords file/DB that will not compromise:
Number of users
User names
User passwords
My basic idea is to hash and salt both the usernames and the passwords, and also to add 1000's of 'trap' entries into the database (for example, random user names ending with _xxxx with random passwords ending with _yyyy which won't be valid for real users).
Of course, when someone tries to log in, I'll have to check it against all lines in the database.
Is this scheme secure?
Notes:
The users are added manually. If a user has to be removed - the login names are stored in a safe.
I'm not sure if I can protect this scheme againt brute-force methods, but I think guessing both name and password is harder
Edit:
I'm protecting against a leak of the user/password file (as well as the application that read this file). As said, I need to protect the actual number of users, as well as their identities (or anything that may disclose their identities).
Number of users seems to be the hardest datapoint to protect. You can mask this by creating large numbers of fake users with nonsense names encrypted as you describe. These can serve double duty as the traps you describe, but then you need to be able to distinguish a trap from a real user which means it is possible for an attacker to do the same if they can compromise the trap-checker.
Who are you trying to secure it against?
Do you want to secure it against someone who compromises the DB, e.g by SQL injection, or a rogue sysadmin?
Do you want to secure it against someone who compromises the OS and gains access to the files that back the database tables?
The former can be mitigated by restricting access to the table to well-reviewed stored procedures, and tough DB access controls.
The latter can be mitigated by putting DB files on an encrypted partition, though this can slow down access and/or complicate startup.
Ironically, the larger the number of users, the more likely a brute force attacer is to stumble on a valid combination - and if they know that you have a lot of users with _xxxx or _yyyy in their usernames/passwords, that may give them a cryptographical advantage.
So, I would absolutely recommend that you give your bogus users no actual privileges, so that even a succesful guess yields no rights to the system.
Secondly, you might want to think about who you're protecting against, and how - it's widely accepted that a good hash/salt combination protects against most credible attacks; adding the username to that scheme just means you're protecting against attacks that don't currently exist.
On the other hand, you're doing nothing to protect against the far more common attack vector of "username on post-it note", "password = sex", etc.
The most common way to improve on "username/password" is to require users to have something physical.