That is actually far less secure.
In an ideal world, where your database is not sitting in the DMZ but is instead only accessible directly from your web server, and then with limited account rights, in order to breach your database and retrieve your hashed password table, I have to:
- Expose your software database connection variables (account/password) by
- Breaching your web server to gain shell access to it
- exploiting a weakness in your application to expose its DB connection variables directly
- Connect to your database. I may need to be able to do this from an SSH to your web server or through hosting compromised code on it, unless I manage to use some form of IP spoofing that is successful in bypassing whatever routing/firewalling you have your database behind (unlikely).
- Retrieve the table. This may not be possible on the account I compromised via step 1, if it is not actually comparing values itself but is instead passing a hash of the current login attempt to a stored proc in the DB on an account that is limited to accessing that stored procedure.
If I can't use your program's account to read the table directly, I'm basically done unless I can either compromise an admin account on the db server or otherwise compromise the db server's VM fully.
And this is all before we get into the question of whether your own hashing scheme is even secure.
In terms of the user names and hashes being "hidden," they're simply not, even if you use compiled code. Things like user names are going to be immediately evident in even a quick pass through with a hex editor.
Security works best with layers that both serve real purposes and decouple raw data into the smallest partitions needed to allow leveraging it as usable information, while only passing the requisite related information in its most minimal form and not the data itself whenever possible
Your approach puts all of the eggs in one basket
My necessary steps that go over the network are:
- Find a way to expose your code for downloading.
That's it. If I get your web server to cough wrong and your code-behind files are able to be pulled down directly, you're done. I don't even need a deeper compromise of the web server than anything that might result in that (which can vary based on whether you have them in an otherwise web readable directory or not). Alternatively, if I find a vulnerability in your code, I could potentially get it to just directly spew out the stored user names and hashes. And of course there's still that same possibility of simply fully compromising your web server.
There is no way to slow down an attack vector like this, presuming you detect a breach at a given level before it has reached other levels: a single breach immediately exposes everything. Even if we're talking compiled software, a skilled attacker will now know not only your hashing algorithm, but also your pepper if you are using one, along with effectively having access to your hashed and salted password table.
To put the second principle more simply, your software itself does not ever actually need to know a given user's stored password directly in order to authenticate them. It just needs to know if the password it has been given is the same as the one stored, which is something the database can determine for it for it, in a way that prevents the credentials your software is using from ever maliciously accessing the database (beyond trying to bruteforce from the stored procedure made available to the software, which presumably you would detect based on # of attempts and velocity and shut down).
Do not roll your own authentication unless there is no other alternative, or you're sure you actually know all of the rationale behind everything you're trying to do, and are willing to duplicate effort that has probably seen more and better review than you will ever get yours passed through. It isn't worth your time, and it will almost always result in something less secure than an established library or package.
If you think you are being clever by doing something different than industry standard practices, think very long and hard about whether or not there might actually be very good reasons behind those practices.
Once user credentials are in someone else's hands, even if you hashed them—even if you knew what you were doing and hashed them well, which is rarely the case when people try to roll their own security—you have to assume they are compromised. It's truly only a matter of time. Your best hashing efforts are only a delay at most in which you have a window to inform users and lock accounts until passwords are reset.