Andrew Milich / 6.05.2023Home / guides

Hashing in JavaScript and TypeScript

Looking to use a hash function for authentication, data storage, or data integrity? Read our article on different hash functions and how to use them in JavaScript and TypeScript.
JavaScript hash functions.

How to compute and use different hashes in JavaScript

Hashing is a key function in any programming language. Hash functions mathematically convert any data - a string, an array of bytes, or even an object - into a number. Hash functions must conform to three critical properties:
  1. They must be deterministic - meaning if you hash some data a to become h(a) , a must always hash to the same value.
  2. They must be collision resistant - meaning that if you hash two different values a and b where a ≠ b , the probability that h(a) === h(b) must be very low (to be more precise, it must be less than 1 divided by the number of possible outputs).
  3. They must not be reversible - meaning that if you have a hash value h(c) , the probability of knowing c is less than 1 divided by the number of possible hash outputs.

Different types of hash functions

Choosing a hash function must be done depending particular needs and constraints. For example, for simple message transfers or verifying data integrity, using a fast hash function - like MD5 - can be a good option. In other cases, like computing salted password hashes for user authentication, a fast hash function can lead to major security risks, like an increased risk of brute force attacks.MD5 (Message Digest Algorithm 5):
  • Outputs a 128-bit (16-byte) hash.
  • Fast.
  • Vulnerable to collisions + brute force attacks.
SHA-1 (Secure Hash Algorithm 1):
  • Outputs 160-bit (20-byte) hash.
  • Slower than MD5 but has demonstrated cryptographic attacks.
  • Not recommended for use due to known collisions.
SHA-256 (Secure Hash Algorithm 256):
  • Part of the SHA-2 hash function family.
  • Outputs 256-bit hash, which adds additional security compared to SHA-1.
  • Widely used in cryptographic contexts - certificates, protocols, verifying authenticity.
  • Slower than MD5 and slower than SHA-1.
SHA-3:
  • Latest Secure Hash Algorithm function.
  • Outputs 512-bit hash.
  • SHA-3 is a part of the broader cryptographic primitive family Keccak.
  • Similar performance to SHA-2, including SHA-256.
Blake2/Blake3:
  • Faster than MD5, SHA-1, SHA-2, and SHA-3.
  • At least as secure as SHA-3.
  • Generally quite widely recommended by cryptographers.
bcrypt and scrypt:
  • More than just hash functions: These are adaptive hash functions that can adjust the computational complexity depending on the context.
  • As a result, these functions are often used for password hashing because of this property, as it helps prevent brute-force and rainbow table attacks.
Argon2id and PBKDF2:
  • We won’t cover these two functions as they are key derivation functions instead of hash functions. However, if you are looking to convert a password into a cryptographic key, these two functions are widely used, with Argon2 being the current state of the art.

Open-source hashing libraries

Using skiff-crypto for simple, reliable hashes

We’ve published the library skiff-crypto to simplify good cryptography practices. Skiff-crypto has powerful functionality for:
  • Asymmetric encryption - Creating keypairs for signing and encryption, then encrypting data using public keys.
  • Symmetric encryption - Encrypting objects, text, and more.
  • Datagrams - Managing object versions, fields, and metadata.
  • Hashing - Generating cryptographically secure hashes.
Skiff-crypto uses the SHA-512 hash function exported from TweetNaCL - for more information on how SHA-512 works, check out the comparison of hash functions above.To use skiff-crypto, check out the NPM link here or GitHub link here. Contributions are welcome!If you’d like to try out skiff-crypto in an example React project, check out the Code Sandbox linked inside the README file. The library is written in TypeScript with full type definitions available.

Using the built-in JavaScript crypto library

JavaScript’s built-in crypto library offers a more flexible and customizable hash function. For example, to generate a SHA-1 hash, you could run crypto.createHash('sha1').update(input).digest('hex'); , where input is a string or buffer object. This function will output a hex digest of the given hash. Similarly, to create a SHA-256 hash (as opposed to SHA-1), you could run crypto.createHash('sha256').update(input).digest('hex'); .JavaScript’s built-in crypto library is also quite reliable, widely used, and extensible.

How to use a hash function

Password hashing

Hashing is frequently used to authenticate users without storing plaintext passwords (an incredibly insecure practice that is never recommended). Instead of storing passwords directly as plaintext, a secure hash of each password is stored. In this case, choosing a hash that is resistant to brute force attacks is quite important. When a user inputs their password, the password is hashed and compared to the stored hash, verifying the user without exposing the actual password. Note that secure authentication practices also recommend salting passwords, which is not covered in this guide.

Fast data lookup

Hashing is widely used in map-based data structures, like hash tables, to quickly retrieve stored data. Hashing can convert keys into array indexes, allowing for near-instantaneous lookup, insertion, and deletion operations. Hash functions can even convert objects to array indices, making them powerful options for storing data. Many programming languages include HashMap support for this reason.Questions?We hope this guide was helpful. If you have any questions, reach out to [email protected], open an issue on the skiff-crypto GitHub, or post on our Reddit/Discord/Twitter.

Join the community

Become a part of our 1,000,000+ community and join the future of a private and decentralized internet.

Free plan • No card required