In your title you are talking about basic authentication, I assume you are talking about HTTP basic authentication, which is when the browser prompts you for a password, encode and sends over the wire. However, you do not really control the mechanisms and encryptions with that method. It's also generally not used because its less secure and you can't add things like SALTs, one time pins, captchas, etc.
Likely, you want to implement form based authentication using an HTML form which sends the form data with POST. You should secure the submission of this form using SSL/TLS with a certificate for general public usage. This helps to limit the ability for man in the middle (MiTM) attacks where an attacker can eavesdrop and capture the username and passwords. You can do encryption on the client side using JavaScript, but you still need the initial password stored up front. I have seen this implementation on only a few pen tests, but its not very common to do it with JavaScript like that.
Now, in regards to salting and hashing, and everything like that. This is more to do with the storage of the credentials in the database. Typically, you receive the password without encryption through the SSL-secured form submission. You don't want to store the actual password in your database, so you hash it and you salt it using your hash algorithm (e.g., bcrypt). The salt+hash make it so you can store the password without it being directly stored. Hashes are one way so unless you use a technique called rainbow tables, you would have to brute force every possibility until you ran through the algorithm and got the same result. Using a salt make it more difficult to use rainbow tables because the rainbow table must take into account the salt and cannot just be the "standard" rainbow table.
You can have a per user salt or one you use universally, a per-user salt would be more secure. In your user table in your database you would store the following
- the username
- the hash(salt+password)
- the salt for this user
Now, when a user comes to log in again they submit their username and password in the form. You then want to see if they are in the table so you then:
- Look up the supplied username in your database and return the hash and the salt
- Take the provided username and rerun the hashing function using the salt obtained in 1 to do somehting like hash(salt+password submit on form)
- If the hash generated in 2, matches the on retrieved from the database in 1 then you know they provided the correct password
The whole point is to not store the actual password and to make it computational expensive to figure out what this random set of characters maps back to (i.e., difficult to determine the real password).
Some further reading
Update
OP Asks about not sending through SSL:
You need to accomplish to separate things here: (1) secure data in transit and (2) secure data at rest. What we talked about with hashes accomplishes securing at rest. To secure it in transit, you need to ensure the data going over the network is encrypted somehow. It sounds like you don't want to obtain or cannot obtain a SSL certificate. This is generally the most common way. Otherwise you could implement a much more complex programatic way, where you have your own private and public keys. You more or less encrypt the data before its sent with your private key using a JavaScript implementation of PGP or similar. This is not recommend because you can easily mess it up and it requires JavaScript, which your users may not have enabled. You still use the salting as described above, you just encrypt at the client with your public key and then decrypt on the server end with your private key, then continue as if it was transfered with SSL.
Algorithm (caveat - requires JavaScript or other client side language enbaled)
- Create a log in form, do not set a submit action in the form - we don't want the information sent through normal means because its confidential and we are not using SSL
- Create a JavaScript handler which is used to submit the form, as part of the processing, encrypt the password field with your private key, then submit it using HTTP post.
- Once received on the server, decrypt with public key
- You have now transfered the actual password over the network with encryption
- Change you private-public key pair frequently to reduce compromise or reversing.
- Continue with securing at rest as detailed above.
Update 2
OP continues question to know more about securing session variables:
It's always best to put all submission over SSL to protect eavesdropping. Even if you hash all of your cookie data, if I can intercept and I just need to send you back the hash, well, I already have it if I can be MiTM. You should use multiple factors to limit session hijacking and CSRF attacks. Rather than going into deep detail here, you may want to check out the OWASP Top 10 and read through the various security concerns and how to mitigate. OWASP is one of the top resources for learning how to secure web apps.
The second question you are asking is if your server side app is doing logic basic on a user id being passed can this be faked? Yes, use session management to determine the current user, don't let the client tell you who they are after authentication.
This article, also related to the questions you ask and may be useful for you.