password hashing using md5 in mongoengine - mongodb

I am using mongoengine(MongoDb ORM) in django.I wan to authenticate the user and his password should be stored in hashed value. Plz help me as mongoengine doesn't give any PasswordField() to store password.
Any other options through which I can authenticate the user login .

Django has two very useful password hashing algorithms built in.
See docs.djangoproject.com, which states
By default, Django uses the PBKDF2 algorithm with a SHA256 hash
and
Bcrypt is a popular password storage algorithm that’s specifically designed for long-term password storage. It’s not the default used by Django since it requires the use of third-party libraries, but since many people may want to use it Django supports bcrypt with minimal effort.
Either one of these two are excellent if you use a large enough number of iterations/work factor; do not use any of the other options. This is made easy by django per the link above:
The PBKDF2 and bcrypt algorithms use a number of iterations or rounds of hashing. This deliberately slows down attackers, making attacks against hashed passwords harder. However, as computing power increases, the number of iterations needs to be increased. We’ve chosen a reasonable default (and will increase it with each release of Django), but you may wish to tune it up
So, in your settings file for a new application, you could increase the work factor with a new subclass:
from django.contrib.auth.hashers import PBKDF2PasswordHasher
class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
"""
A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.
"""
iterations = PBKDF2PasswordHasher.iterations * 100
then put your variant in the settings file, while allowing old PBKDF2-HMAC-SHA-256 and BCryptSHA256 hashes to be read:
PASSWORD_HASHERS = [
'myproject.hashers.MyPBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
]
And also set some password validation:
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 9,
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
To validate an entered password (like on a login page) against a stored password:
check_password(password, encoded)
To generate a new password entry (like from a registration page, where they select or change their password):
make_password(password, salt=None, hasher='default')

Related

Is it "secure" to store a password and username in a .env file in a server to validate an admin API endpoint against?

Context
I've build a RESTful API server in Actix-Web with Rust that's hosted on a Heroku paid plan. It has n amount of publicly available endpoints to access content, alongside 3 strictly admin-only endpoints (for creating, editing, and deleting public content).
I am the only developer who'd ever need to access the admin-only endpoints - and infrequently at that. Several random users will be using the publicly available endpoints daily.
Normally, I'd implement an authentication/authorization strategy akin to this using JWTs (but obviously in Rust for my case). However, the added complexity that comes with this "more common" solution seems overkill for my simple use-case.
My theorized solution
Could I add a username and password field to the .env file in my project like so in order to match against a username and password passed in the admin-only handler functions?
... OTHER KEYS ...
USERNAME = my_really_long_random_username
PASSWORD = my_really_long_random_password
At first glance I'm storing passwords in plain text... but, there's only 1 and it's in my .env file, which is private by default.
All I'd do for the admin-only routes then is this (pseudo-code):
pub fn router_handler(passed_data) -> HttpResponse {
if passed_data.username == env.username && passed_data.password == env.password {
// CONSIDER THEM ADMIN
} else {
// BLOCK THEM AS THEY'RE NOT AUTHENTICATED
}
}
What I've tried
I have yet to try this strategy, but I'm curious about your opinions on it.
Question
Is my theorized solution secure? Does it seem reasonable given my use-case?
Response to question: jthulhu - is this what I do?
So, my .env file should look something like this:
... OTHER KEYS ...
USERNAME = a98ysnrn938qwyanr9c8yQden
PASSWORD = aosdf83h282huciquhr8291h91
where both of those hashes are the results of running my pre-determined username and password through my to_hash function which I added below (likely using a lib like this).
Then, my handler should be like this (psuedo-code):
pub fn router_handler(passed_data) -> HttpResponse {
if to_hash(passed_data.username) == env.username && to_hash(passed_data.password) == env.password {
// CONSIDER THEM ADMIN
} else {
// BLOCK THEM AS THEY'RE NOT AUTHENTICATED
}
}
You should never store passwords in plain text in a server, because if someones breaks in your server, and can read that file, they now have access to everything (whereas they might previously not). Not only that, but most people tend to reuse passwords, so storing one password in plain text means exposing several services where that password is used.
Instead, you should hash the passwords and store the hash. To perform a login, check if the hash of the given password corresponds to the one stored. This mechanism can be used with files or with databases alike, and is pretty much independent on how you actually store the hashes.

Perl Dancer2 Authentication Password Management

So any one who has used perl dancer knows that to authenticate a user on login you can call authenticate_user
authenticate_user(
params->{username}, params->{password}
);
This is part of the Auth::Extensible plugin.
To me it looks like it encourages the use of storing passwords in plain text! Sure you can hash the password first then make sure the stored password is the same hash but this seems to be more of a work around and i found isn't guaranteed to work. I have only got this to work using sha1 which shouldn't be used. I want to use Bcrypt but the passphrase simply wont match. Possibly odd characters not matching i'm not sure.
The thing is using the dancer Passphrase plugin i can already validate the username and password without even needing to rely on authenticate_user to verify them. But for the dancer framework to consider the user logged in you still have to call authenticate_user which must be passed the password.
I'm completely stuck. I'm curious how other people have managed to use proper password management in dancer2?
Firstly, I'll echo the "you almost certainly don't need to be using authenticate_user()" comments. The plugin can handle all that for you.
However, "it doesn't hash it" is wrong; here's how it works. The
authenticate_user keyword loops through all auth realms configured, and for
each one, asks that provider's authenticate_user() method to see if it accepts
the username and password. The Database provider (and the others) fetch the
record from the DB, and use $self->match_password() (which comes from the
Provider role) to validate it; that code checks if the stored password from
the database starts with {scheme} and if so, uses
Crypt::SaltedHash->validate to validate that the user-supplied password (in
plain text, as it's just come in over the wire) matches the stored, hashed
passsword ($correct in the code below is the stored password):
if ( $correct =~ /^{.+}/ ) {
# Looks like a crypted password starting with the scheme, so try to
# validate it with Crypt::SaltedHash:
return Crypt::SaltedHash->validate( $correct, $given );
}
So, yes, if your stored password in the database is hashed, then it will match
it if the password supplied matches that hash.
For an example of what a stored hashed password should look like, here's
the output of the bundled generate-crypted-password utility:
[davidp#supernova:~]$ generate-crypted-password
Enter plain-text password ?> hunter2
Result: {SSHA}z9llSLkkAXENw8FerEchzRxABeuJ6OPs
See the Crypt::SaltedHash doco for details on which algorhythms are
supported by it, and the format it uses (which "comes from RFC-3112 and
is extended by the use of different digital algorithms").
Do bear in mind that the code behind authenticate_user is exactly what's used
under the hood for you.
For an example of just letting the plugin do the work for you, consider:
get '/secret' => require_login sub {
my $user = logged_in_user();
return "Hi, $user->{username}, let me tell you a secret";
};
... that's it. The require_login means that the plugin will check
if the user is logged in, and if not, redirect them to the login page
to log in. You don't need to call authenticate_user yourself, you
don't need to set any session variables or anything. logged_in_user()
will return a hashref of information about the logged in user (and because
the route code has require_login, there's guaranteed to be one at this
point, so you don't need to check).
If you need to check they have a suitable role, instead of just that they
are logged in, then look at require_role in the documentation instead.
In the documentation for Dancer2::Plugin::Auth::Extensible, the description for authenticate_user() says:
Usually you'll want to let the built-in login handling code deal with authenticating users, but in case you need to do it yourself, this keyword accepts a username and password ...
Which strongly implies to me that you shouldn't be calling this function at all unless you're doing something particularly clever.
I haven't used this module myself, but it seems to me that all the hashing and encryption stuff should be handled by one of the authentication providers and if there's not one that covers the case you use, then you can write one yourself.
Whenever I need to store secure passwords for a Dancer app, I reach for Dancer2::Plugin::Passphrase. I wonder if I should consider writing an Auth::Extensible style authentication provider for it.

Hashing payload data when adding a new user in a Facebook Custom Audiences

i need an help with the API to add a user in a custom audience.
Looking at the doc it seems not clear if it has to be hashed every single attribute of the payload.data key or not.
On the documentation (https://developers.facebook.com/docs/marketing-api/reference/custom-audience/users/v2.9) it seems like the hash in not required but in this other article (https://developers.facebook.com/docs/marketing-api/audiences-api) seems like each one of them has to be hashed.
Any thoughts?
Yes, you need to hash everything apart from external identifiers, see this part of the doc:
You must hash your data as SHA256; we don't support other hashing
mechanisms. This is required for all data except External Identifiers.
Before hashing, normalize your data. Only First name FN and Last Name
LN support special characters and non-Roman alphabet. For best match
results, provide the Roman alphabet translation with no special
characters.
External identifiers are just extern_id which isn't applicable to most people anyway.
I'd recommend using one our our SDKs if possible as we handle all of the hashing for you. For example:
use FacebookAds\Object\CustomAudienceMultiKey;
use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
$users = array(
array('ExternId123', 'FirstName', 'test2#example.com', 'LastName1'),
array('ExternId456', 'FirstNameTest', '', 'LastNameTest'),
array('ExternId789', '', 'test3#example.com', 'LastNameTest'),
);
$schema = array(
CustomAudienceMultikeySchemaFields::EXTERN_ID,
CustomAudienceMultikeySchemaFields::FIRST_NAME,
CustomAudienceMultikeySchemaFields::EMAIL,
CustomAudienceMultikeySchemaFields::LAST_NAME,
);
$audience = new CustomAudienceMultiKey('<CUSTOM_AUDIENCE_ID>');
$audience->addUsers($users, $schema);

Salt/Hash for Firebase Simple Login?

Firebase offers 'Simple Login' in which email/password is used for authentication. Does anyone know if firebase salts and hashes the password before storing it? I imagine that firebase would know enough to do so, but I just wanted to make sure, because I could not find anything on this after an hour of searching.
Anticipated follow up: If firebase in fact does not salt+hash the passwords, would the Simple Login work if I took the user's password, salted+hashed, and passed it onto firebase to store/check?
Thanks in advance!
As of 2016
As of 2016, Firebase uses a modified version of scrypt to encrypt passwords. A library to perform the encryption was released on GitHub here.
It uses both salt and hashes as shown in the sample:
# Params from the project's password hash parameters
base64_signer_key="jxspr8Ki0RYycVU8zykbdLGjFQ3McFUH0uiiTvC8pVMXAn210wjLNmdZJzxUECKbm0QsEmYUSDzZvpjeJ9WmXA=="
base64_salt_separator="Bw=="
rounds=8
memcost=14
# Params from the exported account
base64_salt="42xEC+ixf3L2lw=="
# The users raw text password
password="user1password"
# Generate the hash
# Expected output:
# lSrfV15cpx95/sZS2W9c9Kp6i/LVgQNDNC/qzrCnh1SAyZvqmZqAjTdn3aoItz+VHjoZilo78198JAdRuid5lQ==
echo `./scrypt "$base64_signer_key" "$base64_salt" "$base64_salt_separator" "$rounds" "$memcost" -P <<< "$password"`
Pre-2016
According to this page (http://firebase.com/docs/web/guide/simple-login/password.html) Firebase uses bcrypt.
According to the wiki page on bcrypt (http://en.wikipedia.org/wiki/Bcrypt), it both hashes and uses salt with that.

How to use strong encryption for password field using grails with postgresql database?

I had to migrate a legacy database with clear text password to a PostgresSQL database. I've looked up what's the best way to encrypt password in a database and found the pgcrypto extension with slow algorithm. (see pgcrypto documentation for 8.4)
The migration is done for data and everything is working well.
Now I have to write a CRUD application to handle this data.
I'm wondering what's the best way to use this strong encryption with grails ?
In my model, I've used the afterInsert event to handle this :
def afterInsert() {
Compte.executeUpdate("update Compte set hashpass=crypt(hashpass, gen_salt('bf', 8)) where id = (:compteId)", [compteId: this.id])
}
I guess that I should also check if the hashpass field is modified whenever the model is saved. But before that, is there another (best) way to achieve my goal ?
Edit : I cannot use the Spring Security bcrypt plugin here. The CRUD application that I'm writing use SSO CAS so I don't need such a plugin. The CRUD application manages accounts for another application that I don't own. I just need to create a new account, modify or delete an existing one. This is very simple. The tricky part is to hack grails so that it takes into account the password field and use a specific sql to store it to a postgreSQL database.
Edit 2 :
I've come up with the following code but it doesn't work
def beforeInsert() {
hashpass = encodePassword(hashpass);
}
def encodePassword(cleartextpwd) {
// create a key generator based upon the Blowfish cipher
KeyGenerator keygenerator = KeyGenerator.getInstance("Blowfish");
// create a key
SecretKey secretkey = keygenerator.generateKey();
// create a cipher based upon Blowfish
Cipher cipher = Cipher.getInstance(ALGORITHM);
// initialise cipher to with secret key
cipher.init(Cipher.ENCRYPT_MODE, secretkey);
// get the text to encrypt
String inputText = cleartextpwd;
// encrypt message
byte[] encrypted = cipher.doFinal(inputText.getBytes("UTF-8"));
return Base64.encodeBase64String(encrypted);
}
I get a hash that is not a blowfish hash (beginning with $2a$08$ )
Edit 3 :
I've finally came up with a cleaner grails solution after reading this wiki page : grails.org/Simple+Dynamic+Password+Codec (not enough reputation to put more than 2 links so add http:// before) and the bug report jira.grails.org/browse/GRAILS-3620
Following advice from #lukelazarovic, I've also used the algorithm from the spring security plugin.
Here is my password encoder to put into grails/utils :
import grails.plugin.springsecurity.authentication.encoding.BCryptPasswordEncoder;
class BlowfishCodec {
static encode(target) {
// TODO need to put the logcount = 8 in configuration file
return new BCryptPasswordEncoder(8).encodePassword(
target, null)
}
}
I've updated my Compte model to call my password encoder before saving / updating the data :
def beforeInsert() {
hashpass = hashpass.encodeAsBlowfish();
}
def beforeUpdate() {
if(isDirty('hashpass')) {
hashpass = hashpass.encodeAsBlowfish();
}
}
The tricky part is to hack grails so that it takes into account the
password field and use a specific sql to store it to a postgreSQL
database.
Is there any particular reason to do the hashing in database?
IMHO it's better to hash the password in Grails, therefore have a code that is not database-specific and easier to read.
For hashing passwords using Blowfish algorithm using Java or Groovy see Encryption with BlowFish in Java
The resulting hash begins with algorithm specification, iteration count and salt, separated with dollar sign - '$'. So the hash may look like "$2a$08$saltCharacters" where 2a is a algorithm, 08 is iteration count, then follows salt and after salt is the hash itself.
For broader explanation see http://www.techrepublic.com/blog/australian-technology/securing-passwords-with-blowfish. Don't mind that it concerns to Blowfish in PHP, the principles applies for Java or Groovy as well.