简体   繁体   中英

Simple way to hash password client side right before submitting form

Without any common JS libraries, how can I hash a password before sending it?

<form>
    <input type="password" id="pwd" name="password" />
    <input onclick="
var val = document.getElementById('pwd').value;
document.getElementById('pwd').value(sha512(val));"
     type="submit">
</form>

That would somehow be my naive way to do it (with sha512 being a function defined somewhere to create the sha512 value)

Though it obviously does not seem to work. Why? How do I do this right and simple?

I propose you to use jsSHA public sw and put outside your js:

function mySubmit(obj) {
  var pwdObj = document.getElementById('pwd');
  var hashObj = new jsSHA("SHA-512", "TEXT", {numRounds: 1});
  hashObj.update(pwdObj.value);
  var hash = hashObj.getHash("HEX");
  pwdObj.value = hash;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/2.0.2/sha.js"></script>

<form>
    <input type="password" id="pwd" name="password" />
    <input onclick="mySubmit(this)" type="submit">
</form>

Lots of issues here... like hashes without a salt can be rainbow tabled. If you send and then store the hash they make... its like storing a cleartext password now. If the client salts and hashes and then the server salts and hashes it... how do you ensure they can hash again with the correct salt. Bottom line, use a secure connection and then salt/hash on the server.

document.getElementById('pwd').value(sha512(val));

You meant value = sha512(val) .

This would have given you an exception with some helpful error message (eg value is not a function ), so keep the JS console open so you can see the errors.

Note that client-side password hashing is usually an antipattern, and certainly not a workable substitute for proper SSL.

Hashing the password on the client before send it to the server is a complete nonsense and shouldn't be done.

Don't take my word for granted and let's find out why:

The client sends the hashed password to the server. From an attacker point of view, the hash is all it's needed to gain access to the login (ie the attacker spoofs the hash in transit and uses it to gain access to the server).

That's exactly the same scenario as if the client was sending the plain text password. The attacker would spoof the clear text password and use it to login.

So now it's clear that hashing the password on the client side doesn't mitigate the threat scenario in which an attacker is listening for your password in transit. This threat scenario is mitigated by using a secure connection (eg HTTPS).

Hashing the password is still important though: the server should hash the password and compare it to the hashed version stored in the database. Salting is also required, to mitigate rainbow table attacks

I don't think that it is a good idea to hash password in clientside. But you can use CryptoJS

https://code.google.com/p/crypto-js/

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha512.js"></script>
<script>
    var hash = CryptoJS.SHA512("Message");
</script>

You can also use this hash function which is very fast. In the example below you will send to the server the hash of the password.

 const hashCode = s => s.split('').reduce((a, b) => { a = (a << 5) - a + b.charCodeAt(0); return a & a; }, 0); function submitMe() { var pass = document.getElementById('userPwd').value; var enc = hashCode(pass); document.getElementById('userPwd').value = enc; console.log(enc); //for debug console.log(document.getElementById('userPwd').value); // for debug }
 <form action='/login' method='POST'> <input type='password' id='userPwd' name='pwd' min='8' max='16'> <input type='submit' value='SUBMIT' onclick='submitMe()'> </form>

I had success by listening to the submit event , then cancelling the submit , modify the password field with the hash, and then trigger the submit again.

I use the subtle crypto API to calculate the hash . This is built in in the browser, but getting strings in and out is some work.

<script>
    const form = document.querySelector("form");
    form.addEventListener("submit", function (e) {
        e.preventDefault();
        const passwordInput = this.querySelector("input[type=password]");
        crypto.subtle.digest("SHA-384", new TextEncoder().encode(passwordInput.value)).then(function (hashBuffer) {
            const hashArray = Array.from(new Uint8Array(hashBuffer));
            const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
            passwordInput.value = hashHex;
            form.submit();
        });
    });
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM