Custom salt generator in BCryptPasswordEncoder - spring-security

I know that the salt we use to encrypt passwords should be :
They are algorithmically generated from some pieces of data associated with the user, for example, the timestamp that the user
created
They are randomly generated and stored in some form
They are plaintext or two-way encrypted along with the user's password record
Due to the first point, when anyone access to db, set his password for another user, he can not login instead of another user.
but when I use BCryptPasswordEncoder I replace my password in password column of another user and I can login by that user.
In my opinion, it is a security problem, because the admin that access to database can login instead of any user and may do some work. and these works is logged by that user not admin user.
If we use userId or userCreationTime or something like that to generate salt and override
PasswordEncoder#match method, the problem is resolved.
If these points are true my question is:
How can I use a custom salt generator in BCryptPasswordEncoder?

Salting is meant to prevent rainbow table attacks against leaked hashed passwords. With good per-user salting, one rainbow table will not work for the entire db, and an attacker needs to generate a rainbow table per user. This, combined with a computationally complex hashing algo, makes impractical to reverse engineer passwords from a leaked hashed password db.
If someone can manipulate the db, however, you are pwnz0r3d. If an admin can modify the db, they can modify user creation time. They can also "swap" user id with the known value.

Related

Asp net password recovery

I'm using asp.net membership for users accounts, user password is encrypted and stored on to the sql database as a user registers , the problem I'm having it when the user forgets the password I can't get it right when trying to retrieve it from the database, I have no idea how I can reverse the encryption.I'd appreciate the help.
You can't. By default the passwords are saved as a salted SHA1 hash, you can't "decrypt" such a hash.
It would be bad practice to save passwords in a fashion that allows you to view them, no matter which algorithm you would be using for that. Just create some logic to enable a user to reset his or her password, instead of trying to retrieve the original password.

Safe way to store decryptable passwords in ruby

I want to store some keys in an encrypted form in database in a secured fashion. At the same time I need to use the non-encrypted(original) form of the keys somewhere in my code. I planned to use PBKDF2 for password hashing PBKDF2. Is it possible to decrypt the key stored in the database in an encrypted form using PBKDF2. Or Is there any simple and secure procedures available?
Passwords and secret keys are usually stored in their hashed form. That means they are processed through a hash function before being saved to the database. A good hash function such as bcrypt has the following properties:
it produces the same output for the same input
it produces very different output for different inputs
its output is not distinguishable from random
it is not reversible
The last property has a very important security implication: when someone gets access to the database, they cannot recover the original keys because the hash function is not reversible, especially when the hash is salted to prevent attackers from using rainbow tables.
That means if you want to recover the keys later on, you have to save them in encrypted (not hashed) form. An encryption function has similar properties like a hash function, with the key difference that it is in fact reversible. For this decryption step you need a key, which needs to be stored somewhere.
You could store the the key in your application config but that would mean that if someone gains access to your server, they would be able to retrieve the encryption key and decrypt all the stored keys.
I suggest an alternative approach, which will users allow to retrieve only their own stored keys. It is based on the idea that the keys are encrypted with a user-specific password that only the user knows. Whenever you need to perform an action that needs to store or retrieve the keys, the user is prompted for their password. This way, neither yourself nor an attacker will be able to retrieve them, but your program can access them if the user allows it by entering his password.
Store a conventionally hashed user password in the database e.g. using bcrypt
Allow users to store additional password with the following procedure:
Prompt for user password and keys to store
Hash password and compare with database to authenticate
Generate salt for each entered key
Use user-entered password and salt to encrypt keys to store e.g. with AES encryption
Store salt and encrypted keys in database
To retrieve the stored keys in an action requiring them in plain text form:
Prompt for user password
Hash password and compare with database to authenticate
Retrieve encrypted keys and salt from the database
Decrypt stored keys using user password and salt
Be careful to remove user submitted passwords from the application log ;-)
Passwords are never stored in a database in any way that people can decrypt them afterwards. There is no guarantee that someone will not hack your database tables and steal everything that you have stored.
If you store an encrypted (hashed) password for each user, even if your database is hacked, it will take those who stole your decrypted passwords a LOT of time to find out the actual passwords. They can always use your same encryption and compare the resulting hash of common passwords. For example, they can encrypt "MyPassword123" and then compare that hashed password to every password in your database. Weak passwords can still be guessed using this pattern.
Therefore, even non-decryptable passwords have their weaknesses, but if you allow someone to decrypt what you store, then basically it's extremely easy for them to get every single one of your user's passwords. Very bad practice. Some of the biggest and most "secure" companies have had their stored Password Hashes stolen, so you cannot assume you will not be a victim.
I had encountered this same problem with bcrypt using Ruby where it works for user validation since it compares the difference between a user entered clear text and the hashed password and the hashed password never decrypts to clear text. One of the gems I have found that may solve your problem is encryptor, which encrypts using several different keys. So what you can do is to keep your password in the database, while keeping the keys securely in another location (a file in storage).
More information can be found in the rubygems page.
More recent answers to this question:
If you're on Rails <7, use Lockbox
If you're on Rails >=7, encryption is now built in to ActiveRecord

Ruby on Rails User Encryption

I've completed several tutorials of different length and difficulty, a few of them building a custom authentication system from scratch. Most times I seem to find the following way of encrypting the password.
rails generate model User name:string email:string
and then
rails generate migration add_password_digest_to_users password_digest:string
Which produces a hashed password the the development database, when viewed, instead of the password (password1) it shows something like RFTER4dr3wxMnei instead.
Is it possible to add other attributes to the user via this method? For example, if I had two authentication methods (enter username and password) then (enter memorable information) could they both be encrypted using the same method?
or how, in theory, (and if possible) could you use it to encrypt all of the user's data (their name, email, date of birth, password etc)
This is not encryption, it is crystallographic hashing. A hash function is a function that produces a unique output for every input, from which it is impossible (theoretically) to reconstruct the input (short of a brute force attack, or something like a hash table).
Hash functions are perfect for authentication, because it means that you are not actually storing the password. You only store something the you can confirm the correctness of the password with. Every time someone logs in, the password given is hashed using the same algorithm, and the hashes are compared. This way, if someone breaks into your database, they can't actually get the passwords.
Information that you actually need to access, not just verify (you need to verify password, but access DoB, username, etc.) can be encrypted, but then you need to figure out how you are dealing with keys and such, because if someone can steal the encrypted information from the same place as the key, it's effectively pointless.
Worth mentioning: while it's great for learning, don't implement your own authentication systems in production unless you have too. Either use some open source code that has been reviewed by security experts, or use third party authentication that is trusted and secure (Log in with Google, OpenID, Oauth, Log in with Facebook, etc.)

Authlogic multiple passwords per resource

I'm using Authlogic to password protect particular routes. The user is able to share certain pages, and can protect them with a password. I have this working fine for one password, but want to be able to let users have multiple passwords for the same pages.
I want to keep it simple, and not resort to a full username and password. The goal is for simple protection of content via a password.
I know I can override the login method, but it is expecting one object to be returned, and the verify password method is expecting to evaluate one value.
Any thoughts?

Migrating existing user details to new authentication system

Recently I have changed my authentication system to devise. I want to migrate my existing user data to this new system. Previous one was using SHA256 hash to save password. As I know this encryption is one way so in that case what will be the best way to migrate users data to new system. Devise support SHA512 encryption as well but not SHA256 as I know.
Simply upping the hash size isn't buying much security. Please read up on intreated hashes and salting.
Traditionally, you upgrade a password upon the user changing their password. The type of password is either stored with the password (common format: $type$salt$hashpassword), or in an adjacent column, allowing you detect which algorithm to use.
Whether you force users to change their password is your choice.
When a user enters their password (logs in), you can create a devise account for them automatically. That's probably the easiest way to migrate.

Resources