- Simple Javascript Password Encryption & Decryption
- TABLE OF CONTENTS
- DOWNLOAD & NOTES
- QUICK NOTES
- EXAMPLE CODE DOWNLOAD
- CLIENT-SIDE PASSWORDS
- BASIC JAVASCRIPT CRYPTO
- CLIENT-SIDE PASSWORD ENCRYPTION – IT’S BAD
- THE SIGN-UP PAGE
- HOW ABOUT THE DECRYPTION DURING LOGIN?
- WHY THIS IS A WASTE OF TIME
- THE CORRECT WAY
- SERVER-SIDE PASSWORDS
- GET CRYPTOJS
- ENCRYPT-DECRYPT
- WARNING: 2-WAY ENCRYPTION IS PRETTY BAD!
- PASSWORD WITH SALT IN NODEJS
- EXTRA BITS & LINKS
- LINKS & REFERENCES
- OTHER CRYPTO LIBRARIES
- TUTORIAL VIDEO
- INFOGRAPHIC CHEAT SHEET
- THE END
- Leave a Comment Cancel Reply
- Search
- Breakthrough Javascript
- Socials
- About Me
- Генерация пароля с помощью JavaScript
- Простая генерация пароля с помощью JavaScript
- Второй вариант генерации пароля в JavaScript
- Послесловие
Simple Javascript Password Encryption & Decryption
Welcome to a tutorial on how to encrypt and decrypt passwords in Javascript. First, a piece of good news for you guys – Javascript has a native web crypto API that we can use to protect passwords, and there are plenty of free crypto libraries as well.
But now for the bad news – Password encryption only makes sense if you are working on server-side Javascript (such as NodeJS), it pretty much does nothing good on the client side. Just why is that so? Let us explore that in-depth by walking through a couple of examples on both server and client-side Javascript. Read on!
ⓘ I have included a zip file with all the example source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
CLIENT-SIDE PASSWORDS
Let us start with how to do password encryption/decryption on client-side Javascript (that is on a web page or web app). Also on why most web developers won’t bother doing this at all.
BASIC JAVASCRIPT CRYPTO
For the purpose of demonstrating that Javascript is capable of doing crypto stuff, here is an example that uses a good old library called Crypto-JS. Yep, all we do is just plug and play the library to do password encryption/decryption.
CLIENT-SIDE PASSWORD ENCRYPTION – IT’S BAD
THE SIGN-UP PAGE
With the baseline established, let us walk through why client-side password encryption is a waste of time and why you should never do it. Here is a common example of a registration page, where beginners encrypt the password before sending it to the server.
Yep, that’s pretty neat, right? The password is now encrypted and secured. We don’t have to worry about it being “hijacked” by other people when the form is being submitted… So, just what is wrong with this? You will find out in the next 5 minutes.
HOW ABOUT THE DECRYPTION DURING LOGIN?
Next, let us assume that the user data is saved into the server’s database upon successful registration. Then comes the following question – How do we check and confirm the password? Some beginners will just pull the password straight from the server and verify it using Javascript.
WHY THIS IS A WASTE OF TIME
This seems to work at first, but there are a lot of loopholes. Importantly, remember that client-side Javascript runs on the user’s device. Meaning, the source code is downloaded and fully visible to all users. Your secret key and algorithm are just in plain sight… All your “security measures” are worthless. Anyone can reverse engineer and harvest all the passwords. No sweat.
Some of you smarty pants may be thinking “just obfuscate the Javascript then”. Nope. It can still be reverse-engineered. Also, sending the password to the client side for verification is another critical loophole. Encrypted or not. Period.
THE CORRECT WAY
The only correct way to properly protect the password is to encrypt/verify it on the server side. This is the only way to keep the password crypto hidden away from the users. Oh, and if you are worried about the passwords being “hijacked” when the registration form is being submitted – There is a very easy solution.
That is called “just enforce HTTPS on your server”. Yep, once it’s HTTPS, all data exchange between client and server is automatically encrypted . No need for all the manual Javascript encryption gimmicks.
P.S. If you are using PHP on the server side, I will leave links below to my other tutorials on how to create a proper registration and login page.
SERVER-SIDE PASSWORDS
Now let’s move on to examples of how we can do password encryption and decryption in NodeJS. Also on why 2-way encryption may not be the best.
GET CRYPTOJS
To get the CryptoJS library, simply navigate to your project folder in the command line and run npm i crypto-js .
ENCRYPT-DECRYPT
// (A) LOAD ENCRYPT LIBRARY const CryptoJS = require("crypto-js"); // (B) SECRET KEY var key = "ASECRET"; // (C) ENCRYPT var cipher = CryptoJS.AES.encrypt("PASSWORD", key); cipher = cipher.toString(); console.log(cipher); // (D) DECRYPT var decipher = CryptoJS.AES.decrypt(cipher, key); decipher = decipher.toString(CryptoJS.enc.Utf8); console.log(decipher);
Yep, as simple as that. We are still using the same Crypto JS library, and it works just the same as on the client-side.
WARNING: 2-WAY ENCRYPTION IS PRETTY BAD!
Before the hater troll things start to spew acid, I don’t really recommend using 2-way encryption for passwords. I.E. Encrypted passwords that can be decrypted. Consider this – If the secret key is compromised, the bad code ninja can pretty much decrypt and retrieve all the passwords in your system.
PASSWORD WITH SALT IN NODEJS
// Credits : https://ciphertrick.com/salt-hash-passwords-using-nodejs-crypto/ // (A) REQUIRE CRYPTO LIBRARY var crypto = require("crypto"); // (B) CREATE PASSWORD HASH var creepy = clear => < // (B1) GENERATE RANDOM SALT let length = 16; let salt = crypto.randomBytes(Math.ceil(length / 2)) .toString("hex") .slice(0, length); // (B2) SHA512 HASH let hash = crypto.createHmac("sha512", salt); hash.update(clear); return < salt: salt, hash: hash.digest("hex") >; >; // (C) TEST ENCRYPT // Save BOTH the password and salt into database or file var clearpass = "He110Wor!d"; var creeped = creepy(clearpass); console.log("===== HASHED PASSWORD + SALT ====="); console.log(creeped); // (D) VALIDATE PASSWORD var validate = (userpass, hashedpass, salt) => < let hash = crypto.createHmac("sha512", salt); hash.update(userpass); userpass = hash.digest("hex"); return userpass == hashedpass; >; // (E) TEST VALIDATE // clearpass = "FOOBAR"; var validated = validate(clearpass, creeped.hash, creeped.salt); console.log("===== VALIDATION ====="); console.log("Clear password: " + clearpass); console.log("Validation status: " + validated);
So for you guys who are thinking of using 2-way encryption for the convenience of password recovery, you have been informed. The safer way is to do a one-way hash with salt instead. Credits to CipherTrick for this one done with simple SHA512.
EXTRA BITS & LINKS
That’s all for this guide, and here is a small section on some extras and links that may be useful to you.
LINKS & REFERENCES
OTHER CRYPTO LIBRARIES
TUTORIAL VIDEO
INFOGRAPHIC CHEAT SHEET
THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!
Leave a Comment Cancel Reply
Search
Breakthrough Javascript
Take pictures with the webcam, voice commands, video calls, GPS, NFC. Yes, all possible with Javascript — Check out Breakthrough Javascript!
Socials
About Me
W.S. Toh is a senior web developer and SEO practitioner with over 20 years of experience. Graduated from the University of London. When not secretly being an evil tech ninja, he enjoys photography and working on DIY projects.
Code Boxx participates in the eBay Partner Network, an affiliate program designed for sites to earn commission fees by linking to ebay.com. We also participate in affiliate programs with Bluehost, ShareASale, Clickbank, and other sites. We are compensated for referring traffic.
Генерация пароля с помощью JavaScript
Наткнулся на интересное решение для генерации случайного пароля с помощью JavaScript. Код очень короткий и простой, он мне настолько понравился, что я решил написать про него небольшую статейку. Расписывать тут особо нечего, вся генерация сводится к одной строке:
Math.random().toString(36).slice(-8);
На этом можно закончить, но получилось совсем короткая запись, даже по меркам twitter`a. Поэтому добавлю пояснение и еще один вариант генерации.
Простая генерация пароля с помощью JavaScript
Для начала попробуем разобраться, как работает эта короткая строка. Первая часть кода Math.random() генерирует случайное число от 0(включительно) до 1(не включительно), то есть создается произвольное число с большим количеством знаков после запятой, например: 0.7642436524728753 . Далее с помощью метода toString(36), полученное длинное число, переводится в строку. Самое интересное, что при переводе можно указывать основание системы счисления, которая будет использоваться при переводе числа. Таким образом, число превращается в набор символов и чисел, получится что-то подобное: 0.rigjv73pl7 . И в конце с помощью метода slice() отрезается нужное количество символов. Если методу передать один отрицательный параметр, то отсчет символов будет с конца.
Когда все стало понятно, также стали очевидны и недостатки кода. Максимальное количество символов, которое может содержать пароль, это 10-11 штук. Также есть очень маленькая, даже практически невозможная, возможность получить ошибку. Ошибка произойдет, когда сгенерируется число 0, без длинного хвоста или когда сгенерируется 0.5 – такой вариант тоже возможен. Но эти недостатки ни сколько не принижают эстетическую красоту кода генерации пароля в одну строку:
var randomstring = Math.random().toString(36).slice(-8);
Можно оформить код в небольшую функцию, которая будет генерировать пароль с заданым количеством символов:
function gen_password(len) < if(len >10) len = 10; len = len * (-1); return Math.random().toString(36).slice(len); >
Второй вариант генерации пароля в JavaScript
Бывает необходимость генерировать пароли длиннее 10 символов, а также иногда необходимо использовать в пароле не только буквы и цифры, а еще и другие случайные символы. Для таких случаев можно воспользоваться этим способом:
function gen_password(len) < var password = ""; var symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!№;%:?*()_+="; for (var i = 0; i < len; i++)< password += symbols.charAt(Math.floor(Math.random() * symbols.length)); >return password; >
Послесловие
Когда дописал статью, вспомнил, что на блоге уже есть подобная функция, только написана она на php: почитать.
Спасибо за внимание, пишите красивый код!
P.S. Если не получается красивое решение, то пишите красивые костыли…