Authenticating against a Database. Hashing a password - symfony

How do I hash a password to store it in DB if bcrypt is used as algorithm?
security:
encoders:
Hoax\PartnerBundle\Entity\Partner:
algorithm: bcrypt
I tried this code, but it returns different results all the time:
$factory = $this->get('security.encoder_factory');
$user = new Hoax\PartnerBundle\Entity\Partner();
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword('ryanpass', $user->getSalt());
$user->setPassword($password);

I am not too familiar with bcrypt, but the symfony docs give you the answer to your question. And although it is best practice in most cases to use the Symfony2 salt method, it looks like bcrypt incorporates the salt into the password. Read the bcrypt section of the symfony docs.
A salt for each new password is generated automatically and need not be persisted. Since an encoded password contains the salt used to encode it, persisting the encoded password alone is enough.
This is why the password is different each time. The hash itself already has the salt stored in there. So the password 'password' will have a different hash each time it is 'bcrypt'ed because it includes the salt

Related

How to hash realmdb password

I want to create/update realmdb password on path __password.
I cannot find clear documentation about it, i just explore realm studio and realmdb graphql API.
From realm studio i found salt, digest (sha512), and hash.
From that key i produce sha512 hash with https://www.convertstring.com/Hash/SHA512.
the problem is, character length from sha512 just 128 character. i tried to compare with other hash password, they have 684 character.
the other key i found inside path __password such as iterations and keyLength, i don't know what that for.
actually i can use this API for create user.
Realm.Sync.User.login([**serverURL**],Realm.Sync.Credentials.usernamePassword([**username**], [**password**], true));
but i want to update password too. there is no documentation about changing password.
the question is :
How i can produce sha512 with output 684 character ?
How to update realm password directly to path __password ?
What is best practice to update user password ?

AES-256 best practices implementation

I'm reversing an app but I'm not very expert of the AES algorithm.
The application gives the user the opportunity to make an offline login.
The user is asked to provide his username and password
This is the function that is used to store the info of the user
public void EncryptLoginInfo(string username, byte[] secretShared, byte[] salt)
{
byte[] random = calc.GenerateRandomBytes();
byte[] array = aes.Encrypt(secretShared, random);
OfflineLogin loginInfo = new OfflineLogin()
{
Username = username,
SecretShared = array,
Iv = random,
Salt = salt
};
this._userCredentials.StoreOfflineLoginData(username, loginInfo);
}
And this are the info that are stored inside an internal config file of the app. In the example below, the password passed to the encryptLoginInfo is 123
Username: not_important
SecretShared: 4KVrjy1cQVWYpWF7aolpMS0HzhKyFf+9VXauQrXoXVUbf0bGXIDOLDJuSVhYoFo2
Iv:yil4nn02IoKsOnX5KXVsDg==
Salt: 5kJio2VQEqjomHRdQMqRVJ0zkBsmqi8K3NypC2VWJk4
If the user want to make an offline login, he is asked to provide username and his password.
Question: Is this algo safe? If an attacker is able to obtain SecretShared+Iv+Salt is he able to recover the password of the user (that in this specific example is 123)
This is the decrypt function
public void DencryptLoginInfo(OfflineLogin loginInfo)
{
byte[] array = aes.Decrypt(loginInfo.SecretShared, loginInfo.Iv);
loginInfo.SecretShared = array;
loginInfo.Iv = (byte[]) null;
}
Are you able to spot any security issues in this implementation? The algo used should be AES-256.. Are you able to implement a POC in python to decrypt the PASSWORD given SecretShared+Iv+Salt?
According to your comment, your goal is to authenticate the user. For that we use password base key derivation functions on the password. Often people refer to this as "hashing passwords", which is unfortunate terminology because "hashing" can mean anything. But the main point is that we do not encrypt passwords, instead we send them through a one-way function that is designed to be slow. The slow speed deters brute force attacks.
You do not need an IV to do this. Instead, your app should be deriving a salt and and using a password based key derivation function (sometimes referred to as a "password hashing" algorithm: you will have to excuse that the industry has made a mess out of the terminology on this topic). You can find guidance on this all over the web. But I suggest you have a read of point 4 in Top 10 Developer Crypto Mistakes to see common pitfalls in implementing this.
Don't use openssl to convert a password into a key (or password hash)! The algorithm in openssl is weak. Openssl's EVP_BytesToKey() fails to meet the requirements of slow speed, meaning that it is easy to brute force your key from your password.
The proper solution to this problem is to use an algorithm such as bcrypt or pbkdf2 (Java implementations can be found without much effort) to derive a "hash" from the password. You then verify that the user typed in the password correctly by re-doing the same computation with the user entered password and the salt that was stored for this password. If they match, access is granted, otherwise access is denied.
Note that if this app interacts with a server, normally you do password verification on the server side. If your app does not interact with a server, then you may have a good reason to do it on the device. I don't know what your app does, so I cannot tell you what is right or wrong for you.
A great reference for doing this properly is How to Safely Store Your Users' Passwords in 2016 .

bcrypt vs pbkdf2 for encrypting private keys

I'm building an application in which a password is used on the client side to encrypt a private key of a elliptic curve key pair. Then the password is bcrypted and sent to the server (along with the encrypted private key) and the public key.
Originally, I was using pbkdf2 to hash the password before encrypting the private key, but since I'm also bcrypting the password, could I use the bcrypted one instead?
According to https://medium.com/#mpreziuso/password-hashing-pbkdf2-scrypt-bcrypt-1ef4bb9c19b3#.sj4jcbynx the answer is not only yes, but bcrypt is even better as it's more GPU-ASIC resilient. Anything I'm missing?
You should not be using the bcrypt hash output as an encryption key; it is not meant to be key material:
BCrypt is not a key-derivation function
BCrypt it is a password storage function
You have an elliptic curve private key that you want to encrypt using a user's password. Of course you don't want to use the password directly - you want to use the password to derive an encryption key. For that you can use:
PBKDF2
scrypt
These are both key-derivation functions (e.g. password-based key derivation function). Their purpose is to generate an encryption key given a password. They are designed to be "hard".
You feed both these algorithms:
a password
cost parameters
salt
desired number of bytes (e.g. 32 ==> 32 bytes ==> 256 bits)
and it returns you a 256-bit key you can use as an encryption key to AES-256.
You then want to backup the user's key
I gather that you then want to:
store the encrypted elliptic curve private key on your server
store a hash of their password on your server
And your question was: since you already ran their password through "a hashing funtion" can't you just use that hash as their stored password?
No! That hash is also the encryption key protecting their private key. You don't want that private key transmitted anywhere. You don't want it existing anywhere. That 32-byte encryption key should be wiped from memory as soon as you're done with it.
What you should do, if you also wish to store a hash of the user's password is use an algorithm that is typically used for password storage:
pbkdf2 (a key-derivation function abused into password storage)
bcrypt (better than pbkdf2)
scrypt (a key-derivation function abused into password storage; better than bcrypt)
argon2 (better than scrypt)
Update: Argon2/Argon2i/Argon2d/Argon2id is weaker than bcrypt for password authentication (read more)
You should separately run the user's password through one of these password storage algorithms. If you have access to bcrypt; use that over pbkdf2. If you have scrypt, use that for both:
derivation of an encryption key
hashing of the password
The security of your system comes from (in addition to the secrecy of the password), the computational distance between the user's password and the encryption key protecting their private key:
"hunter2" --PBKDF2--> Key material
"hunter2" ---------bcrypt-------> Key material
"hunter2" ----------------scrypt----------> Key material
You want as much distance between the password and the key.
Not-recommended cheat
If you're really desperate to save CPU cycles (and avoid computing scrypt twice), you technically could take:
Key Material ---SHA2---> "hashed password"
And call the hash of the encryption key your "hashed password" and store that. Computation of a single SHA2 is negligible. This is acceptable because the only way an attacker can use this is by trying to guess every possible 256-bit encryption key - which is the problem they can't solve in the first place. There's no way to bruteforce a 256-bit key. And if they were to try to brute-force it, the extra hashed version doesn't help them, as they could just test their attempt by trying to decrypt the private key.
But it's much less desirable because you're storing (a transformed) version of the encryption key. You want that key (and any transformed versions of it) stored as little as possible.
To sum up
generate EC key pair
encryptionKey = scryptDeriveBytes(password, salt, cost, 32)
encryptedPrivateKey = AES256(privateKey, encryptionKey)
passwordHash = scryptHashPassword(password, salt, cost)
and upload
encryptedPrivateKey
passwordhash

How can I set a password of a user doc for a Meteor app running on Modulus?

I have a Meteor app running on Modulus and I need to set (not reset) a user's password.
There is the Accounts.setPassword() method, but it can only be executed from server code.
However, I'm not aware of something like meteor shell for Modulus.
How can I run server code?
The source code of Meteor tells us how exactly passwords are hashed:
// Use bcrypt to hash the password for storage in the database.
// `password` can be a string (in which case it will be run through
// SHA256 before bcrypt) or an object with properties `digest` and
// `algorithm` (in which case we bcrypt `password.digest`).
//
var hashPassword = function (password) {
password = getPasswordString(password);
return bcryptHash(password, Accounts._bcryptRounds);
};
And also:
Accounts._bcryptRounds = 10;
Thus you can simply create a new hash by first applying SHA256 and then a 10-round bcrypt on the raw password string.
If you only have one or two passwords to modify, and wish to update them by hand, here are some online tools to do that:
Online SHA-256 calculator
Online bcrypt calculator
After you created a new hash, just update it using the Mongo console:
db.users.update({"emails.address": "my#email.com"}, {$set: {"services.password.bcrypt": "$2a$10$u/4JV2MrAKb8Jk9yRHDIL.yGn5SQOInFunvUwEnDv5uJgMkWNe08K"}});
I ended up adding a Meteor method which does what I need.
However I don't really like the idea of it and think there should be a better way.

Hashing using SHA1 as inner-most hash in a chain

A client program (over which I have no control) is authenticating by sending me a password, hashed as SHA1(password).
I'm reluctant to store the password hashed using only SHA1 in my database, so I'm proposing to store passwords in the database hashed as SHA256(SHA1(password)) (where the password is hashed over multiple iterations using PBKDF-2 or something similar).
My question is: is there anything insecure about the inner-most hash using SHA1 in this scenario? I realise that the probability of collisions will be increased, but since this is just for storing passwords in the database I don't think I need to be concerned about that. Is there anything else that I'm missing?
Consider adding a salt which is unique-per-row before doing the final encryption. Example:
Lets say that you receive W6ph5Mm5Pz8GgiULbPgzG37mj9g= (a SHA1'd encryption of "password"). That is associated with a User, who should have a unique key, such as a UserID and/or UserName.
My suggestion - to avoid collision - would be to do a conversion of the Bytes to a Base64String (in C# this would be Convert.ToBase64String( byteVariable ) - then concatenate onto the string the user's unique-ID (making the new string something like:
W6ph5Mm5Pz8GgiULbPgzG37mj9g=+103 (where I added +103 to reflect the user's ID) - then apply your SHA256 algorithm. This will produce: mNXRjWsKJ7V+BHbAuwJJ7neGT+V1IrLQSQXmb4Vv1X8= - which you can store in your database. A SHA256 hash - which eliminates the collisions from the less-safe SHA1 algorithm.
And - since you are using 1-way encryption - when you go to check whether the password is valid in the future, you simply append the user's ID again before checking.
If the client always sends you the same password, simply SHA1 hashed, then the SHA1 hash output is the password, to all intents and purposes. Treat it and store it the same way you would any other password, such as by using PBKDF2, SCrypt, or BCrypt.

Resources