Migration of users from asp.net identity 2 to firebase authentication - firebase-authentication

I have a .net application which uses asp.net identity 2 in order to authenticate users. The users login using username/password and upon successful login an access token (JWT) and a refresh token is produced.
The default implementation of asp.net 2 for hashing the passwords can be found here.
It uses a key derivation function with random salt to produce the hash. The salt is included as part of the output of the kdf. Thus the final produced password hash consists of a first empty byte, then 16 bytes of the salt and then 32 bytes of the hashed password. From the above references we can see that the algorithm used is HMAC-SHA1 with 1000 iterations and the raw password of the user
as key for the HMAC (see here).
I am thinking on migrating to Firebase Authentication and I want to migrate my existing users there. Based on Firebase documentation when migrating HMAC_SHA1 hashed passwords we must include the password hash, the salt and the hmac key. Also, we cannot provide the number of iterations used by the sha1 hashing algorithm (see here).
So, the question is: How can we know the key of the hmac since it is the raw password of the user? This is the default implementation of asp.net identity 2. Since we can never know it this means that we cannot migrate our users to firebase authentication?
Also, even if we knew the key, how could we provide the 1000 iterations of the sha1 algorithm in the payload towards Firebase? This can be done only when the hashing algorithm is sha1 without hmac see here.

I can help on the firebase part of the question.
The SDK does not seem to provide all the functionality supported by the Firebase CLI.
If you take a look here:
https://firebase.google.com/docs/cli/auth
firebase auth:import ACCOUNT_FILE \
--hash-algo=HASH_ALGORITHM \
--hash-key=KEY \
--salt-separator=SALT_SEPARATOR \
--rounds=ROUNDS \
--hash-input-order=HASH_INPUT_ORDER
I think you can define everything you need.
For hash-algo you need to use HMAC_SHA1
For hash-key you need to use the key used to hash the passwords in base64 format
For rounds use 1000 for the iterations you specified
For hash-input-order you need to use SALT_FIRST
Now for where you can get the key, maybe someone else can chip in.

Related

What is the "simple" hashing algorithm that CouchDB uses to encrypt passwords?

(TL;DR: I have two questions at the bottom.)
I have been looking through CouchDB's documentation to learn about its hashing algorithm, but I'm unable to find important details.
The most information I've gathered has been from this page: 1.5.2. Authentication Database
Here's my problem:
I have a bunch of users in a _users database in my CouchDB instance on Cloudant.
I need to be able to migrate users from CouchDB to Firebase.
Firebase offers a super-handy-dandy auth migration tool for this. However, in order to utilize its auth migration tooling, I need to know exactly which hashing algorithm is being used for the "simple" password_scheme.
For every user in my _users database, I have the "salt" and "password_sha" available.
Given the name "password_sha", I assume that the "simple" "password_scheme" uses either SHA1, SHA256, SHA512, PBKDF_SHA1, or PBKDF2_SHA256.
None of the users' docs in my database have a "derived_key". Almost all of them do not have a defined "password_scheme". If any of them do have a defined "password_scheme", it is always "simple" (and never "pbkdf2").
Once I know exactly which hashing algorithm CouchDB uses, I then need to know how many rounds or iterations were used to hash the password.
The Firebase docs say:
"you must provide the number of rounds (between 1 and 8192 for SHA1, SHA256 and SHA512, and between 0 and 120000 for PBKDF_SHA1 and PBKDF2_SHA256) used to hash the password."
However, I cannot find any documentation/information on this.
So my questions are:
What is the hashing algorithm CouchDB uses for the "simple" "password_scheme"? (Is it SHA1, SHA256, SHA512, PBKDF_SHA1, PBKDF2_SHA256, or something else?)
How many rounds or iterations are used to hash the passwords?
I posted this same question to a few chats linked in the CouchDB homepage, and Robert Newson, owner of CouchDB, told me the following in Slack:
"simple" is a one round of SHA-1 (with salt)
https://github.com/apache/couchdb/blob/main/src/couch/src/couch_passwords.erl#L26
So to directly answer these two questions:
The "simple" CouchDB hashing algorithm uses SHA1.
And it is only one round of hashing.
Just for the sake of completeness, this simple scheme is not what more recent versions of CouchDB (for sure not >= 2) use. The current default is to use pbkdf2 with the following values:
iterations = 10
keylen = 20
size = 16
encoding = 'hex'
digest = 'SHA1'
see couch-pwd if you need to generate or validate CouchDB-style passwords.

ArangoDB Nonce Workflow

The ArangoDB docs discuss a couple nonce functions here:
https://docs.arangodb.com/3.1/Manual/Appendix/JavaScriptModules/Crypto.html
I understand the idea that I would create a nonce, send it to the client, hash a password with the nonce and send it to the server. But I don't really understand how these two functions work together to make this all happen.
Can someone elaborate on this documentation and the process? If I hash the nonce and the password together, how do I compare it to the stored password that's already hashed? Just looking for some guidance on the process. Thanks!
Update with more details:
I'm working on auth code. I guess in general I'm trying to understand the two functions in the ArangoDB crypto library and how they work together. The documentation doesn't elaborate very much. I found this workflow on wikipedia:https://en.wikipedia.org/wiki/Cryptographic_nonce But I'm not sure I understand it.
Client login page requests a nonce from server. Server provides. Does the server then store this nonce is the users session for later retrieval?
Client hashes password with nonce from server and a client created nonce as well and sends the username, client nonce, and encrypted password to the server.
How does the server compare the password hashed with the nonce & client nonce, to the already hashed and stored password in the database? Instead of hashing the password with the nonce & cnonce, should it just be encrypted using one of the nonce's as a key?
The ArangoDB crypto library provides two functions createNonce, which is obvious, but then it provides checkAndMarkNonce. How does this fit into the workflow? How can I check the returned nonce unless I store it in a session var? And how can I check the nonce if it's hashed along with the password? Is this wikipedia example just wrong, or am I missing some key components?

Create asp.net Identity User in SQL

This question is a revised version of the previous one (I deleted that one)
I have a site running (C#) MVC 5 and ASP.Net Identity 2.0. From within the site all user management functions works fine, create, update, delete.
We have a SQL job that created all the accounts in bulk on the previous version of the site, I now need to update this to create the new accounts in Identity 2.0. I can't find any information on how to do this in any of the available forums.
Any information would be appreciated.
I've done some work on it an the last issue I have is figuring out how Identity 2.0 encodes the password. I can't seem to find out what algorithm is used.
This is how Identity 1 encoded the password:
SET #encoded_hashed_password = dbo.fbase64_encode(HASHBYTES('SHA1', Cast(#salt as varbinary(MAX)) + CAST(#ClearTextPassword AS varbinary(MAX))))
I'm looking for the Identity 2.0 equivalent.
It uses the same algorithm you will find in System.Web.Helpers.Crypto to hash and verify the passwords. To hash the password the method HashPassword can be used. The password hash is generated with the RFC 2898 algorithm using a 128-bit salt, a 256-bit subkey, and 1000 iterations. The format of the generated hash bytestream is {0x00, salt, subkey}, which is base-64 encoded before it is returned.
It is not clear to me from the question whether the previous site used SimpleMembership. If it was here is an article that provides detailed steps to migrate to ASP.NET Identity and how you can just use the same hash for your passwords.

Best practice on generating reset password tokens

Any best practice on how a reset password token should be constructed? I'm thinking:
random 17 characters [a-zA-Z0-9] + a globally unique id + random 17 characters [a-zA-Z0-9].
Is there a better solution, or an industry standard on reset password tokens?
There are some important points to consider.
The code should be really random (read from MCRYPT_DEV_URANDOM), and should not be derrived from other user related information.
Ideally the code is base62 encoded (A-Z a-z 0-9) to avoid problems with the Url.
Store only a hash of the token in the database, otherwise an attacker with read access to the database can reset any account.
This leads to the problem that you have to find the hash of the token in the database, after the user clicked the link. There are two possible ways to store the token:
You hash the token with a hash algorithm like SHA512 without a salt. This is secure if the token is very strong (minimum length 20 with 0-9 a-z A-Z). Theoretically you have to check whether such a hash already exists before you enter it in the database, in practise this is negligible. I implemented a password-reset class that can handle such tokens.
You hash the token with BCrypt and salt. This allows for shorter tokens, but you cannot search for the hashed token in the database. Instead you have to include a row-id in the link to find the token.

How to generate a password the same as what django generates?

I'm using django.contrib.auth.hashers.make_password method to store passwords. There is an iOS app that sends username and password to my django site to get authenticated. I want them to send encrypted password not the raw password. But I don't know how django encrypt the password? How someone else in other platform can generate the same encrypted password?
Django has a variety of methods it can use to encrypt passwords. By default is uses PBKDF2.
You can look at your PASSWORD_HASHERS list to see what is set:
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher',
)
Here is a SO article on implementing that algorithm in iOS:
PBKDF2 using CommonCrypto on iOS
The challenge will be that the password is salted. If you don't know the salt, you can't hash the password correctly. So you'll need to send the salt securely to the device, so your output hash matches.
version <1.4 is SHA1, >=1.4 is PBKDF2, check the table
select * from auth_user;
to make sure, the password column is algorithm$hash
check document for details.