I've been struggling with this for some time now, hopefully someone has done this before and can help me on my way. I went to the Firebase people to request the scrypt params in order to migrate our user authentication away from Firebase to our own server. Now I got those params, but I have no clue as how they should map towards the node scrypt package (https://www.npmjs.com/package/scrypt). The Firebase params are of the following format:
hash_config: {
algorithm: SCRYPT,
base64_signer_key: asdf1234
base64_salt_seperator: xxxx
rounds: 123456
mem_cost: 098765
}
Somehow these should map onto the nodejs scrypt params, but I can't find the similarities. Any help would be much appreciated!
Struggled a lot with getting scrypt work properly. The documentation from here https://github.com/firebase/scrypt#password-hashing looks like outdated. Decided to share knowledge how we did things correctly in our team.
Working command
scrypt {key} {salt} {saltSeparator} {rounds} {memcost} [-P]
No need for salt+separator concatenation and base64 manipulations.
Firebase uses a custom version of Scrypt for user authentication. We take the derived key from standard scrypt, and then AES encrypt it with a "pepper", stored with the hashed password.
We just open sourced Firebase's version so that you can do your own password verification. Check it out at github.com/firebase/scrypt
I've been running into the same problem with migrating my firebase users over. I've also been going back and forth with firebase technical support - they said they couldn't share their hashing libraries unfortunately. As an alternative I've migrated my users over to my new db and checked for the "salt" variable whenever someone signs in. If the salt exists then query firebase, otherwise query your own db.
Related
I've been looking at implementing JWT for the first time using jsonwebtoken (https://github.com/auth0/node-jsonwebtoken). For that, I need a secret value.
Is there a recommended command, or site, to generate a sufficiently good one?
I found this page (https://security.stackexchange.com/questions/95972/what-are-requirements-for-hmac-secret-key) which goes into detail about how long a secret should be (the answer seems to be a 256-bit), but where do you get one from? :)
Else it seems the other option would be to use a public/private key pair. They seem to prefer that approach on this guide I found: https://medium.com/#siddharthac6/json-web-token-jwt-the-right-way-of-implementing-with-node-js-65b8915d550e since that guy says he started off using a string and then switched to using a key pair. However the complication is this will be running on Lambda so I would ideally like the secrets (string or key) to be in environment variables. Not kept as files. But if you put a certificate in an environment variable, I wonder if AWS will strip out newlines and so screw it up when Node tries to work with it. So I'm thinking a secret string would be simpler - as long as it is sufficiently strong.
Thanks!
This is what I did when implementing HapiJS with JWT2. I generated a key based on the documentation they provided. According to their repo, this is one of the simplest ways to generate a secure key to sign against for JWT.
node -e "console.log(require('crypto').randomBytes(256).toString('base64'));"
I don't think you have to use asymmetric key authentication with public/private keys for JWT. In simplest forms, when a user logs into your system, they are given a hash of user data. On the client side, you provide that hash in the authorization header with each request. The server will check the hash to verify integrity. Since you have the key that you hashed against, it's highly unlikely that they will be able to create a forged hash.
Check out this link to the GitHub issue where they discuss generating keys for Hapi-auth-JWT2.
At work, we want to upgrade our node app authentification a little by using a unique salt per user.
We are already using passport and passport-local with our hand-written password validation, storing password hash in DB and salting with a common salt.
I want to upgrade it correctly. One of the first rule of security I know is not doing it oneself : https://crackstation.net/hashing-security.htm
However, I'm having trouble finding a decent, trustable npm module to handle that. Searching npm with "salt" or "auth" yielded those modules :
https://github.com/florianheinemann/password-hash-and-salt
https://github.com/davidbanham/hashPass
Their documentation is unclear and they have less than 10 stars on GitHub.
Can someone point me to a good module for hashing/salting/checking my passwords ?
Bcrypt (npm)
Choose bcrypt module for generating hash with salt. Also note that it will make slow ur node app. Single encrypt decrypt operation takes around 100ms
[edit] Explanation : How To Safely Store A Password
I know how to "safely" store a password in the database in NodeJs and use it as a user login for example.
But know I have a different question, where I'm not sure what might be best practice.
I am using amazon product api, so I have to provide different aws Id's.
So I thought, storing them as a plain text might not be that sure, so I hashed them.
But when sending my request to the amazon Api via the code snipped below, I somehow have to safely restore the "correct key", because the hashed one will not be accepted then.
var opHelper = new OperationHelper({
awsId: 'XXXXX',
awsSecret: 'XXXXX',
assocId: 'XXXX'
});
Is there some opposite way of
crypto.createHash('sha256').update(awsId).digest('base64')
So to make my it more clear, how to restore a hashed key from my database so that I can use it in the amazon request again?
Or am I getting things totally wrong and I do not have to store them hashed in my database?
Thank you for letting me know
There is no way to reverse a hash without brute force.
This is the point of a hash.
Sorry
While creating a Twilio Zap (and others), we are required to provide the Account Sid and the Account Token for your existing Twilio account.
I suppose this is stored by Zapier somewhere (hopefully with reversible crypto), otherwise they cannot execute future requests. Does anybody know how safe is this? Have they published any information about how they protect this data?
EDIT
Well, nothing some googling couldn't help
https://zapier.com/help/data-privacy/
Yes, they encrypt the data with AES and store the keys separately. I guess there will always be the danger of data breaches, but that's the trade-off.
I just wonder why their own login credentials use SHA (with 1000 iterations), while I believe the most recommended would be bcrypt.
Zapier co-founder here, we've recently updated to use PBKDF2 with 10k iterations (the standard Django hashing scheme). We'll progressively update these from time to time as standards dictate.
I'm wondering what is the state-of-the-art of transmitting passwords from a web form and storing them in the data store.
A lot of recent posts point to bcrypt, however, there are no pure Python implementations, which is a requirement for App Engine.
Any suggestions?
Best practice? Use the Users API with either Google Accounts or OpenID, so you're not storing or transmitting passwords in the first place.
If you must do it yourself, transmit the login data over SSL, and store the password hashed, salted, and strengthened, using a scheme such as PBKDF2.
You can use PyCrypto which has been ported to google-app-engine.
You should never store the actual passwords, of course. Storing a hash should be sufficient. When the user enters his password, you hash it again and compare it to the stored value.
You should of course only receive passwords over https, which is supported in google-app-engine (albeit only through you appspot domain)
BCrypt has been ported to Python some time ago. I've been using it gracefully since then.