I use the mentions software stack above and I need to encrypt password before save into database. I also need to decrypt password because when someone will change password he she needs to give in the old password and then the new onw twice and I need to check the old password.
I have searched a lot but I still not sure what is the right way to do this.
I have found this link Encrypting but are there other hints to do this?
I also not sure if maybe MongoDB provides something to protect passwords.
First read Steven CarlsonĀ“s answer about password hashing.
The good thing is that Spring Security will do this for you. Spring Security 3.2 introduced the new org.springframework.security.crypto.password.PasswordEncoder interface and some implementations: BCryptPasswordEncoder, StandardPasswordEncoder (and NoOpPasswordEncoder).
Important: Do not confuse org.springframework.security.crypto.password.PasswordEncoder with the old deprecated org.springframework.security.authentication.encoding.PasswordEncoder
The interface (and therefore the implementations) has the two methods you need:
public String encode(CharSequence rawPassword)
public boolean matches(CharSequence rawPassword, String encodedPassword)
I recommend to use org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder.
The BCryptPasswordEncoder (in contrast to the StandardPasswordEncoder) use an salt that is different for each password (but not global like the one from StandardPasswordEncoder). When you encode a raw password (public String encode(CharSequence rawPassword)) then the returned encoded password is not just the encoded password, it also contains some meta information about the used hash-algorithm, the used salt and of course the encoded password.
You should not be "encrypting" the password at all. I know this sounds counter-intuitive. But there is zero reason your system should need to decrypt the password. To do so would open your database to a hacker, because if you store your decryption password in your codes/server a hacker can steal that information.
The correct process is to hash the password. A hash is a one-way (cannot be decypted back to the original text) process. The current standard would be to use SHA256 to hash your password. Here is a basic flow-chart:
Take user submitted password. Example password "mypass" would hash out to ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
Store this hash (ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222) in your database.
When a user logs in you take the password he just submitted and hash it. If he enters the same password it will hash out to the same value in your database.
When a user goes to change passwords you hash the "enter your old password" to verify the old password still matches, if it does you hash the "enter your new password" and save it.
One thing I did not mention in my example is salt. This is something you must use in your system as it protects your data from rainbow table exploits. But that is for another discussion.
Hope this helps :)
Related
I am trying to implement a basic authentication system for a Go server that consists of users with multiple server-generated passwords (tokens essentially) which must be securely stored in a database.
One way of accomplishing this would be to hash the passwords with a one-way function and a globally unique salt.
However, since users have multiple passwords in my case, this creates a problem for authentication; each of the user's passwords would likely have a different salt, so the server would need to iterate through the passwords in the database, hash the supplied password using the same salt as the one in the database, and then compare. This does not seem efficient.
Alternatively, I was thinking that I could relax the "globally unique" constraint on the salt and randomly generate a salt when the user is created, and use it for all that user's passwords. With this, I would only need to hash the user-supplied password once, and could then use an SQL query to perform authentication. This is also the solution suggested in this related question.
However, the Go x/crypto/bcrypt package does not expose a function which hashes passwords with a custom salt, its salt generation is private. Is this for a good reason? Are there vulnerabilities with this approach of using a common salt for all of a user's passwords?
This problem seems common enough given that sites like GitHub and GitLab would have to deal with it for their personal access token storage, yet it appears that GitLab (by default) simply performs a sha256 hashing on their generated tokens.
By design each hash would have it's own salt, this is stored in the database. as a string with the salt, password hash, bcrypt passes etc. It appears all or most newer gen cryptography does this so each hash would have to be cracked individually. If you want something stored in your code I'd add a pepper to every password and then let their salts be unique in the db.
You're worried about efficiency of iterating over each password but I wouldn't be, security is probably better than your login efficiency. Just store their login session for x days?
Are there vulnerabilities
Well yes, bcrypt itself is considered vulnerable if that's an answer?
I think you should go with argon2id since it is what is considered "good" today, and since your program is new
https://pkg.go.dev/golang.org/x/crypto/argon2
This is a wrapper so it is safe as far as the Go crypto is concerned, and very easy to use:
https://github.com/alexedwards/argon2id
If you're wanting tokens you should probably use UUIDs
There is no option to convert hashed text back to plain text. Thats the reason why we use that method to store password - only the author of a password can know the real value - nobody else (developers and someone who can stole passwords). The popular method used to break hashed password is called "brute force attack" and is based on comparing already known hashed values of popular passwords to existing ones in database.
Now i need to show current password when user change password. but hash password cant not return back.
how to solve this issue?
convert hashed password to normal password?
Encryption is a two-way function; what is encrypted can be decrypted with the proper key.
Hashing is a one-way function that scrambles plain text to produce a unique message digest. With a properly designed algorithm, there is no way to reverse the hashing process to reveal the original password.
Now i need to show current password when user change password. but hash password cant not return back. how to solve this issue?
You do not need to show the password to anyone, including the owner of the password.
If you want to check, you can use check method, allows you to verify that a given plain-text string corresponds to a given hash.
if (Hash::check('plain-text', $hashedPassword)) {
// The passwords match...
}
I have some different requirement, i don't want to decode the password, but i am building some other app based on SAME DATABASE for LOGIN so what i can do to "encrypt the password value so that it matches the backend password encrypted code".
I want to provide LOGIN from CODEIGNITOR app where data base is created by admin app in LARAVEL ... this is the issue...
So through CodeIgnitor if someone is LOGIN the password will be encrypted equivalent hash encrypted laravel application code.
The Encrypted Password is
$2y$10$cwd15HRgON0ytqkkV5F9zupfUOkqaii7fpbB9Kjd9I7W46LRYY0Km
And the real PASSWOORD is
123456
Please help...
Caddy DZ's answer is right, but to better answer your question you should know that every time you generate a new password with bcrypt function, a new random salt is used.
This leads you to end up getting a different hash for the same password each time you generate one.
The only way you have to verify the correctness of the password, is to use a built-in php function called password_verify.
That function will hash your password (that you provide as a second argument) with the same salt that has been used to generate the stored password (the salt to use is stored in the password hash) you already have in the database:
$password = '123456';
$saved = 'your stored hash';
if (password_verify($password, $saved)) {
echo 'Correct password.';
}
You can check the documentation about password_verify
This is not standard encryption that can be decrypted, this is hashing which is only one (1) way encryption..
To make this work in, you need to use the same hashing algorithm between the two apps (Laravel and CodeIgniter)
For instance laravel uses bcrypt by default to hash the password, so you need to configure CodeIgniter to use the same or vice versa.
bcrypt for codeigniter
I want to add a number of test user accounts and it's a lot faster to do it directly from the Database.
There are a couple of fields that I cannot figure out:
secret_token: How do I generate this on the fly? Is it necessary? Can I copy it from other accounts?
password: Even though I have created some accounts the normal way (register page), with the same password, the password fields are different for each user. Therefore I assume it's not a simple copy/paste case (question also applies to changing a user's password from the DB).
Any insight appreciated, thank you.
secret_token is an md5 hash, and is created by the User::generateActivationToken() method. It is used for special account activities like email verification, password reset, and password creation for new accounts.
password is a 60-character salted hash generated by password_hash using the bcrypt function. Since the salt is randomly generated each time a password is created, it will be different from user to user, even if their plaintext passwords are exactly the same. Indeed, this is the purpose of using a salt.
If you are just setting up test accounts for development purposes, you can leave secret_token empty and use password_hash to generate passwords (perhaps by running a custom PHP script from the command line).
If you need to generate accounts in bulk for real users, you may want to set a secret_token but leave the password empty, generate a "password reset" event for each user, and then send them a password creation email so they can choose their own passwords. This is in fact what is done in the createUser controller method:
$data['password'] = "";
...
$user = new User($data);
...
$user->newEventPasswordReset();
You can see the code for newEventPasswordReset here.
Let's say an application has really specific data which belongs to a user, and nobody is supposed to see it except the owner. I use MySQL database with DataMapper ORM mapper. The application is written in Ruby on Sinatra.
Application behavior:
User signs up for an account. Creates username and password.
Logs into his dashboard.
Some fields in specific tables must be protected.
Basically, I'm looking for auto-encryption for a model properties. Something like this:
class Transaction
include DataMapper::Resource
property :id, Serial
property :value, String, :length => 1024, :encrypted => true
... etc ...
belongs_to :user
end
I assume that encryption/decryption on the fly will cause performance problems, but that's ok. At least if that works - I'm fine.
Any ideas how to do this?
I wouldn't store any data that relies on the user remembering their password and then using that password to decrypt the data. What are you going to do when the user changes their password? Decrypt/Encrypt everything? I doubt it. What if the admin reset the password? All data lost? Again, I doubt it.
See the other links about storing secrets but please don't use any value from the user as part of your encryption.
So you want to store the data encrypted in the database? Firstly, I would ask you to consider why you need to do this? You should be able to write your application such that only the authenticated user can get to their own data.
If you do genuninely need to store encrypted data, that you also need to be able to decrypt (as opposed to a one-way hash) then there is lots about encryption in ruby here: http://www.example-code.com/ruby/encryption.asp
You certainly should encrypt/decrypt data on user side - otherwise there is no point in encrypted storage, as tracks of private data still there somewhere - in network cache, in swapfiles of different kind etc. Moreover, data can be sniffed with Man-In-The-Middle attack.
So what you probably want is javascript-based client-side encryption. Topic is greatly covered in http://javascript.about.com/library/blencrypt.htm (Rijndael encryption algorithm), and there is great AES implementation library on http://www.movable-type.co.uk/scripts/aes.html
You should encrypt data before submission of form (with onClick callback of "Submit" button f. e.), and then pass to server and process as usual.
Drawback is that you can't use any Rails with such data - only client-side javascript.
I had to do this for encrypting sensitive data. I wrapped the strongbox gem and it's on github: http://github.com/bitzesty/safe
The safe gem provides Public Key Encryption of AR attributes.
You use a one-way hashing algorithm. Hash the password and store the hash. Then whenever the user enters his password, you hash the password entered and compare it to the stored hashed password. If they're the same, you let them through. If not, they're denied.
It's generally not a good idea to ever store a user's password that can be taken to plaintext.
Typically it is stored as a salted hash of either MD5 or SHA1.
So, you have a random salt, store it in the user's table, and then you hash their pass and the salt, like this:
$hash = md5(md5(salt) + pass)
I would recommend against storing a pass that can be returned, the only way I'd recommend you store it is in a one way hash.
That said, there are some encryption schemes that you can use, such as RSA encrytion. This way, your application will encrypt the user's password that it receives from the end user using your public key, and when you need to decrypt it, do so using your private key. There's really very limited application for storing a key this way (such as providing a log in to another site automatically) and is typically frowned upon.
attr_encrypted may be also solution for encryption sensitive data, works with ruby class or ActiveRecord, DataMapper, or Sequel in Rails.
https://github.com/attr-encrypted/attr_encrypted