I do not quite understand how you are doing your session, if it is by HEADER Basic at every request.
Ex: HTTP Authentication Basic MD5 (username: password)
If it is, I would advise using the flow password of the OAUTH2 .
That nothing is more than persisting the user session in a database and traffic an identifier instead of access data, of course with some endpoint name conventions and parameters.
Now regarding the encryption methods I would definitely indicate bcrypt.
Why?
MD5 always generates the same hash, ie if you cryptograph a value, the hash for this value will always be the same, this facilitates the attacker who with some effort can go hashing until it reaches its value.
example:
Se eu fizer o hasg desse texto:
MD5("The quick brown fox jumps over the lazy dog") = 9e107d9d372bb6826bd81d3542a419d6
Se fizer denovo, da o mesmo valor:
MD5("The quick brown fox jumps over the lazy dog") = 9e107d9d372bb6826bd81d3542a419d6
Bcrypt always generates a different hash, which when compared to another generated hash it returns whether it is valid or not.
example:
Se eu fizer o hash desse texto:
Bcrypt("The quick brown fox jumps over the lazy dog") = "$2a$10$o2o0OMLJh4M6EQuF9Tk/Ceidt/JSFOpPzNl6WSIQV9ip.VyrlW8py"
Se eu fizer denovo, o valor sai diferente:
Bcrypt("The quick brown fox jumps over the lazy dog") = "$83e912b45ea3cbd8f99163323dt/JSFOpPzNl6WSIQV9ip.1313aC"
Mas se você comprar os dois atraves de uma função do Bcrypt
Bcrypt.compare("$83e912b45ea3cbd8f99163323dt/JSFOpPzNl6WSIQV9ip.1313aC", "$2a$10$o2o0OMLJh4M6EQuF9Tk/Ceidt/JSFOpPzNl6WSIQV9ip.VyrlW8py") == true
Basic conclusion, comparing the hash through a (purposely) slow function, makes it very difficult and slow for the attacker to arrive at the correct value, then preferably to bcrypt or some comparison algorithm for stealth data.