How to safe store password in database? [closed] - php

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I wonder about creation password storage tool for my company, based on PHP or NodeJS. Currently we keep passwords in KeePass but it's not good for sharing password between employees.
We need to keep passwords, not hash. I just looking for good practices how to store passwords in safe way. How to encrypt password? Are there any open tools to encrypt passwords?

Doing this right is not for the newbie/faint of heart.
In order for the system to be secure then the passwords should be held in a form which is not readable by anyone without access. Storing the (complete) access method in the application means the data is not secure. Hence the passwords need to be stored with some sort of reversible encryption but the key must not be stored on the server.
Unfortunately you need to know the key in order to put encrypted data into the database. With symmetric encryption (same key for encryption and decryption) that's not too much of a problem if everyone gets access to all the passwords - but that is very limited in its value and in most cases would undermine security.
The solution is, when setting or updating a password, to encrypt it with an asymmetric cipher using the public key of each user whom should have access - resulting in multiple copies of the encrypted password each of which can only be decrypted using the private key of the user.
Hence each password would be represented by a series of records, one for each user, containing the relevant user identity, the encrypted password, an initialization vector, and the target account for the password. You would also need to retain public keys for each user, and provide a mechanism for them to bring the encrypted data and their private key together - sending the data out in an email would one solution. Allowing a user to upload their private key is not a good idea. You might store the private key on local storage on a browser and decrypt in Javascript.

Related

How To Secure My Api Used For Customer Login Without Making It Vulnerable To Others [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am very new to development with angularjs.
I am creating a user login system using angularjs.
I created a user login system using angularjs using json data.
But using my api link in controllers is vulnerable to anyone who is inside the source code to my login page.
I want to secure my api to be unvulnerable to anyone. Using the source code can help anyone to see all the users to my platform. Also if I am hashing the password then also some techy might decode the password.
Please help me with angular or json to secure my login platform.
When you create a hash password, you can add salt value into that password then after you can create a secured hash password.
You can use bcrypt:
const salt = bcrypt.genSaltSync(+20);
const hash = bcrypt.hashSync(userId, salt);
return hash;
Another user can decode this password but they can not create the same.
bcrypt is not an encryption function, it's a password hashing function. Hashing is mathematical one-way functions, meaning there is no* way to reverse the output string to get the input string.
*of course only Siths deal in absolutes and there are a few attacks against hashes. But none of them are "reversing" the hashing.
create a password:
const salt = bcrypt.genSaltSync(+20);
const generatedPassword = bcrypt.hashSync(data, salt);
we can compare a hash password
data=Test#123
hash=******
ex:const comparePassword = bcrypt.compareSync(data, hash);
You will get your password is matched or not

Appropriate encryption for financial data [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I'm currently building a web application(PHP/MySQL) which saves data from persons. Most of this data is not worth protecting with encryption but some of it is financial information like income and so on. It is not a payment application and does not store information that could be turned into money directly like credit card information but still stuff you don't want to have in a possible leak. This platform has to be sold to customers that want "security", but that can mean anything as the customers themselves do not have any knowledge what they really want, since they are business people and not cryptographers(like me neither).
It is a management platform so the people that have their financial data saved there are not the users of the platform. Users of the platform are merely a login with permissions attached to them. The server itself never has to have access the data. Every operation is done by a user(could also be an admin) that is logged in. Multiple users need to have access to the same data given they have enough permissions.
My question is now how I can protect the financial data from these threats:
Somebody finds an SQL-injection and dumps all tables remotely
Somebody steals the hard drive of the server (database + code)
Where I'm certainly not going: Large scale sniffing attack or compromised servers(like sniffing all traffic on the server itself where SSL doesn't matter) or social engineering/phishing.
I would also like to have a quick summary how much more information(keys, data, etc.) I have to store in comparison to the current system, where there is one simple field for income etc. and a standard login system with username and hashed password.
EDIT: Reformulated question almost entirely following the suggestion of comments/answers
Here are two approaches to this:
1) Use symmetric encryption because you have already arranged a secret with the client, which is their password.
Whenever the user requires access to their sensitive information, they need to provide their password. If you require this, then you can use that password as a basis of generating the encryption key.
You can use the openssl functions in PHP to encrypt the sensitive data, and decrypt it when the client needs it. This will allow you to select an appropriately hard to break algorithm which OpenSSL supports. The drawback of this is that you will need explicit user permission and their password to access that data, which is good if you're only storing it on behalf of that user, but bad if you need to pass it on to someone else.
This way you will not need to store additional information in the database. In case someone steals your hard drive, all they will have is encrypted sensitive data and hashed passwords. The drawback is that it's a single point of failure, if they break the encryption they also get the password and vice-versa however the difficulty of breaking the encryption is not as high as reversing a hash. It also relies on strong passwords, which as we know users often don't tend to use, however that's not a new problem and one we're not likely to solve today.
2) Require the user to generate a private-public key pair and send you the public key. You can then store this public key and encrypt data using it. This generally would work well if you had an app/software that communicates with your server, which can do this on the user's behalf, but is harder to implement in a web application. Perhaps there's JavaScript libraries that can do this but since it's not something that is commonly done you need to be 100% sure the library you're using is secure. However this also requires of the user to store the key somewhere and be able to use it whenever they want access to that data (again JavaScript can do this for the user but saving and loading the key is something that requires user interaction due to security concerns).
In short:
Symmetric encryption would only be secure if the encryption key is not stored on the server but is something that the user can provide whenever it is needed.
Asymmetric encryption is even more secure but unrealistic in a web application targeted to an average user.
So I would suggest symmetric encryption using the user's password as a key.
From your question, the following key points stand out.
The server itself never has to have access to the data.
Multiple users need to have access to the same data given they have enough permissions.
Maintain security even if:
Somebody finds an SQL-injection and dumps all tables remotely.
Somebody steals the hard drive of the server (database + code).
This is possible to achieve, but not trivial. The thing that makes this possible is the fact that the server does not require access to the data. This allows us to use user passwords to derive keys.
Each level in your permission structure will have an associated key. This key will be used to encrypt data that can be viewed with those permissions. When the first administrative account is created, generate a key for each level in your permission structure and use the administrative password as an input for a KDF and derive a key. Use this password-derived key to encrypt each permission key and store the resulting ciphertexts alongside the administrative account.
As new users are created and assigned ranks by the administrative account, pull the highest level permission key that the new user will have access to, as well as any keys at a lower permission, decrypt them with the administrative password (which will be required for creating users) and then encrypt them again with the new users password and store alongside the new user in the database.
This system allows you to pass the required encryption keys to each user and makes accessing data above the users permission level cryptographically impossible.
At this point, it is rather straight forward for you to allow users to access data by simply taking their password, decrypting the relevant permission key and then using that key to decrypt the data. Users changing their password is also trivial as it simply means you have to decrypt the permission keys with the old password then re-encrypt with the new password.
At a more technical level, I would recommend the following:
Use AES. AES-256 tends to be the most common but AES-128 is just as secure in the grand scheme of things. Use of an authenticated block mode (GCM) isn't as important here but is still recommended. If not, use a mode like CBC or CTR with an HMAC.
Never use a password directly as a key. Use PBKDF2 to generate keys from passwords. Using AES-256 fits in nicely here because you can use SHA-256 as the primitive to PBKDF2 and get output the same length as the internal hash function.
Generate a new random IV every time you encrypt using a CSPRNG. Prefix the IV to the ciphertext. Don't derive an IV from PBKDF2 like the key.
Asymmetric encryption and hybrid encryption are pointless here unless the users generate and retain ownership of the private keys themselves. I infer from the rest of your question that this isn't the case.
Assuming you want to be able to view this encrypted information without user interaction (e.g. you aren't just storing this information for the user and the information is relevant to your business operations), you have limited storage options.
If your exact threat model is to protect this data in the event of a database leak and nothing else, symmetric encryption is perfect, if properly implemented.
The implication of this is that the symmetric key must be stored on servers that make requests to the database and serve the data to your other (likely front-end) systems. If any of those servers were to become compromised, then the encrypted data will be leaked.
In summary, use symmetric encryption, but understand that it will only protect you directly from a database leak through something like SQL injection or a similar attack. A compromised server is a compromised server and generally means full data access given enough time.
EDIT: If you intend to require user interaction to view the secured data, then apokryfos's comment above accurately details what to do to secure the information. Generate a symmetric key from the users password and use this to encrypt an additional symmetric key. Use this secondary symmetric key to actually encrypt the data. Using two keys makes a user password change easier.

PHP and MySQL encrypting passwords with a Caesar shift? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a PHP login system where I check the username that the user inputted and cross check it with every username in my database. If there is a match it looks at the password and if there is a match again it will grant the user access to their profile. If not they will be redirected to the login screen. I currently store passwords as what they actually are, not encrypted or anything. I was wondering if it is possible to get the password the user inputs when signing up, use an algorithm I will programme such as replace each letter with its corresponding number(a bit more complicated than that obviously). I would then store the password as the output and when reading it in from the database it would be decrypted. Is this safe, if i make my own algorithm or can someone easily look at my code and decipher it?
Do not store encrypted or (shudder) plain text passwords.
If you need to store a password value, store the return from a cryptographic hash function. There's no need to "roll your own" cryptographic hash algorithm. (The strength of a cryptographic algorithm is not produced by keeping the algorithm "secret".)
Cryptographic hash algorithms are the workhorse of modern security.
https://en.wikipedia.org/wiki/Cryptographic_hash_function
When you need to test a password (by comparing a submitted password to a stored password value), just run the submitted password (to be tested) through the same cryptographic hash function, and take the return from that and compare to the stored hash value. If the hash values match, then there is an extremely high probability that the plaintext passwords match. If the hashes don't match, then you are guaranteed that the passwords don't match.
To directly address the specific questions you asked:
Q: Is [my proposed implementation] safe?
A: The short answer is no, it's not safe. The first part of my answer describes a better approach to handling password tokens for authentication.
Q: If i make my own algorithm or can someone easily look at my code and decipher it?
A: The strength of a cryptographic algorithm is not found in keeping the code "secret".

How does service salt work? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I want to know how service salt works. I know how to bcrypt password and give each user an unique salt. But I heard there is also another layer you can add by having a service salt. I am just curious how that works. What is the difference between that and an unique salt generated for the user?
Here's where I saw the term service salt: Web Application - Storing a Password
The "service salt" (described as "a sitewide static salt" in the question you cite, and also sometimes called "pepper" in crypto literature) is simply a secret string which is fed to the password hashing algorithm along with the password and the per-user unique salt.
The point of having a "service salt" like that is that, unlike the per-user salt values, the service salt is not stored in the database but somewhere else (typically in a configuration file, or hard-coded into the application). Thus, it protects the passwords against attacks that only compromise the database but don't allow the attacker to access the app configuration. With modern web apps, such an attack scenario is not as unlikely as it might seem; for example, a simple SQL injection attack would often fit this scenario.
One detail to keep in mind is that, unlike the per-user salt, which just needs to be unique and not too easily predictable, the "pepper" actually has to contain a substantial amount of entropy (say, 128 bits) and must be kept secret for it to be of any use.
In any case, including such a secret constant in the password hash calculation is pretty easy, so there's very little reason not to do it: even if your password hashing algorithm doesn't explicitly support it, you can just, say, append the "pepper" to each password.
"The benefit provided by using a salted password is making a lookup
table assisted dictionary attack against the stored values
impractical, provided the salt is large enough. That is, an attacker
would not be able to create a precomputed lookup table (i.e. a rainbow
table) of hashed values (password + salt), because it would take too
much space. A simple dictionary attack is still very possible,
although much slower since it cannot be precomputed."
Source: http://en.wikipedia.org/wiki/Salt_(cryptography)
A salt prevents reverse checks against rainbow tables that are meant to hack passwords easily. The "salt" converts something easily hackable into something more difficult for a hacker to decrypt.
I would highly reccomend that you toy around with this api;
http://www.openwall.com/phpass/
It does all that nitty gritty password generation for you without you needing to be a security expert. Additionally, it has fallbacks built into it to work with older/weaker systems.

Two-key encryption/decryption?

I'm looking to store some fairly sensitive data using PHP and MySQL and will be using some form of reversible encryption to do so since I need to get the data back out in plain text for it to be of any use.
I'll be deriving the encryption key from the users' username/password combination but I'm stumped for what to do in the (inevitable) event of a password being forgotten. I realise that the purpose of encryption is that it can only be undone using the correct key but this must have been addressed before..
I'm trying to get my head around whether or not public key cryptography would apply to the problem but all I can think of is that the private key will still need to be correct to decrypt the data..
Any ideas?
It's not clear what you are striving for, so advice on how to implement it is hard.
Standards like PGP and S/MIME encrypt each message with a new symmetric key. Those keys are then encrypted for each recipient of the message. This way, instead of duplicating the message (which could be very large) for each recipient, everyone gets the same ciphertext, and only the key (which is small) is duplicated—but encrypted differently for each recipient.
Maybe you could do something similar here, encrypting the key with the user's password, and encrypting another copy with your public key. If the user forgets their password, you can recover the message for them (after an appropriate backup identity verification) using your private key.
The conventional solution is to have a "recovery agent": one user that holds a second password that can be used to decrypt all data. Strict usage policies would apply to using the recovery password, such as putting it physically into a safe.
Then, either encrypt all data twice: once with the user key and once with the recovery key; alternatively, generate a session key for every set of data, and encrypt the data only once, but the session key twice.
For that to work, at least the key of the recovery agent must be asymmetric, since the private part will live in the safe, and the public key in the software.
As yet another alternative using the same scheme: encrypt the user's passwords with the recovery key on password change. This is simpler to implement, but will allow to recover the passwords and not just the data, which may be undesirable.
I'm looking to store some fairly
sensitive data using PHP and MySQL and
will be using some form of reversible
encryption to do so since I need to
get the data back out in plain text
for it to be of any use.
Protecting sensitive data is good. Now:
Whose data is it? (yours, your user's, or a third party?)
What does it need to be protected from? (disclosure, corruption (accidental or intentional...)
Who does it need to be protected from
Uninvolved parties goes without saying.
Do you need / want to avoid accessing the plaintext data yourself (useful for deniability),
Do you need to protect either your user's data from being visible to a third party,
Or a third party's data from the user,
Or your data from the user or a third party?
What are likely attacks?
Do you need to protect in the case where the server is completely compromised?
Do you need to protect against an application level attack where the user simply gains access to some but not all available data (e.g. access to the SQL database, but not the filesystem)?
Will the amount of data be small enough that the attacker can guess and simply check whether he/she got it right? (short passwords, numbers, simple words, fixed form text are likely candidates)
Will the attacker have known plaintext with which to attack?
Is it better for the data to go away (or to re-retrieve the data) if the user forgets their password, or is it worth an increased risk of exposing the data to avoid that cost?
There are probably other questions, but this is the type of thing you want to think about when using encryption. The answers will help you figure out what you need vs. what you want, and will probably help point in the right direction. You might not want to share all of the answers with us.
I'll be deriving the encryption key
from the users' username/password
combination but I'm stumped for what
to do in the (inevitable) event of a
password being forgotten. I realise
that the purpose of encryption is that
it can only be undone using the
correct key but this must have been
addressed before..
You might have decided on a solution without considering the impact. That doesn't mean the solution is wrong, but this question suggests you should think about what you are willing to risk for security. Sometimes data will be risked.
I'm trying to get my head around
whether or not public key cryptography
would apply to the problem but all I
can think of is that the private key
will still need to be correct to
decrypt the data..
This too sounds like a solution in search of a problem. Public key cryptography is useful when you have two (or more) separate actors with an interest in communicating data between them. Those actors can be real (people) or functional (components of a system), but without two actors, there is no reason to have a separate public and private key.
Basically, if you encrypt something, and lose the encryption key, you're screwed.
When it comes to securing data, you need to consider why you're securing it, and what you're attempting to secure it against. And what tradeoffs are worth making in order to do so - the only truly secure system is one that is completely isolated from the internet, which is a level of security that is self-defeating for most applications.
So here are some questions to ask yourself:
If someone compromises my database, is it acceptable for them to be able to access this data?
What if someone compromises my entire application stack?
If the answers to the above two questions are "no", then the key material must be held by the user. And they will lose access to their data if they lose the key.
You can provide an option for manual key recovery if you also have a "master key" that you don't store anywhere near your application, only you hold it and you use it to manually reset passwords. If that's also not an option (say, only the user should be able to access the data, not the system administrator), then you're going to have to make a compromise somewhere.
This is a question I have thought about myself and as I see it the following options are available (with option #1 being the most secure):
Provide no reset password functionality - if they have forgotten their password then they are locked out.
Generate a new secure master key and encrypt & hash the user's key with this master key and store the cipher text and hash result in the database. The secure key is then made known to the user either by adding it to a file that the user downloads, emailing to the user or displaying the secure master key on screen. To reset the password the user would have to enter this master key which is then hashed and compared and if they match, the user's key in the database is decrypted.
Ask the user to provide 2 security questions and answers when registering; hash the answers and store the questions and answer hash in the database. The second answer is used as the master key to encrypt the user's key. To receive a password reset request email the user has to answer the first question correctly. Once they click the link in the email the web page then asks the second question, if this is correct and the query string parameter values are valid then use the answer to the second question to decrypt the user's key.
Use an application global master key (maybe stored in the web/UI application and use this to encrypt and store the user's key. Once a user is verified through a password reset email process the user's key is decrypted using the application global master key and then reencrypted with their new password.
In summary, the benefits of each option is as follows:
This is the ultimate for security and would possibly be the only option if the data was critical to be kept encrypted. However, in the real world people forget their passwords as sure as the sun rises and not providing a reset password function could be a bad commercial decision.
This is secure as the master key is not stored on the front end or database so if the platform is compromised then the data would require some significant effort to decrypt. However, the downside is the user could still lose their master key anyway.
The weakness here is if the database is compromised the answer to the question could be researched and then used to decrypt the users encrypted key.
This approach leaves the application key in the stack leaving your data vulnerable if your platform is hacked. The only protection you have is that if the database server is hacked then the data would still be safe.
As with most things in the world of software development you need to consider what is best for what you are trying to accomplish and aim for the correct balance.
Why are you using a different key for every user?
If you choose one key, it is much easier to handle.
Store your encryption key outside of the database.
Your application will still have to have access to it, but someone with a db dump will not be able to read the encrypted info.
Generate a random session key.
Use the session key to encrypt the data.
Encrypt the random key with any number of user passwords that you need.
This way you can use any user password to decrypt the data.

Categories