mirror of
https://github.com/LukeHagar/website.git
synced 2025-12-09 12:57:48 +00:00
Add password hashing algorithms blog
This commit is contained in:
105
src/routes/blog/post/password-hashing-algorithms/+page.markdoc
Normal file
105
src/routes/blog/post/password-hashing-algorithms/+page.markdoc
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Demystifying password hashing algorithms
|
||||||
|
description: What are password hashing algorithms and how they help secure user credentials in your application
|
||||||
|
date: 2023-10-20
|
||||||
|
cover: /images/blog/password-hashing-algorithms.png
|
||||||
|
timeToRead: 7
|
||||||
|
author: aditya-oberai
|
||||||
|
category: authentication, security
|
||||||
|
---
|
||||||
|
|
||||||
|
In today's digital world, securing sensitive information such as passwords is of paramount importance. Password hashing algorithms play a crucial role in protecting user credentials and ensuring the integrity of authentication systems. In this blog, we will delve into the intricacies of password hashing algorithms, explore their key characteristics, and discuss some of the most widely used and secure algorithms to help you make informed decisions when implementing password storage and verification in your applications.
|
||||||
|
|
||||||
|
## What is a password hashing algorithm?
|
||||||
|
|
||||||
|
**Password hashing algorithms** are specialized mathematical functions that transform plaintext passwords into unique, fixed-size outputs, known as hashes, which are then stored in databases. Through the use of techniques such as salting, adjustable work factors, and memory hardness, modern password hashing algorithms are designed to thwart attacks and keep user data secure.
|
||||||
|
|
||||||
|
The mathematical process of password hashing involves applying a hash function to a combination of a password and a salt, iterating the process based on a work factor, and, in some cases, incorporating memory hardness to increase the computational complexity.
|
||||||
|
|
||||||
|
This function would operate as follows:
|
||||||
|
|
||||||
|
`hash_result = HashFunction(Iterate(Combine(password, salt), work_factor), memory_hardness)`
|
||||||
|
|
||||||
|
Where:
|
||||||
|
|
||||||
|
- **`Combine(password, salt)`**: Combines the password and salt, possibly using concatenation or a more complex operation.
|
||||||
|
- **`Iterate(data, n)`**: Repeatedly applies a hash function 'n' times to 'data' to increase computational complexity.
|
||||||
|
- **`HashFunction(data, memory_hardness)`**: Applies the primary hash function to the data and optionally incorporates memory hardness.
|
||||||
|
|
||||||
|
The result is a fixed-size hash that is unique, deterministic, and resistant to reverse engineering, ensuring the secure storage and verification of passwords. For example, inputting a string `loremipsum` into a hashing function that uses the SHA-256 algorithm would output `5245a52778d684fa698f69861fb2e058b308f6a74fed5bf2fe77d97bad5e071c`.
|
||||||
|
|
||||||
|
### Characteristics of password hashing algorithms
|
||||||
|
|
||||||
|
Password hashing algorithms have certain characteristics:
|
||||||
|
|
||||||
|
- **One-way function**
|
||||||
|
Password hashing algorithms should be one-way functions, making it computationally infeasible to reverse-engineer the original password from the hash output, preventing attackers from trying to retrieve user passwords from the stored hashes.
|
||||||
|
- **Deterministic**
|
||||||
|
A password hashing algorithm must always produce the same hash output for a given input to ensure consistency and reliability.
|
||||||
|
- **Fixed-size output**
|
||||||
|
Password hashing algorithms must produce a fixed-size output (hash) regardless of the input size. This is necessary when verifying the password inputted by comparing it with its hash.
|
||||||
|
- **Slow computation**
|
||||||
|
Unlike general hashing algorithms, which prioritize fast computation, password hashing algorithms should be intentionally slow to compute. This characteristic makes it more time-consuming and resource-intensive for attackers to perform brute-force attacks or attempt to guess passwords using a large number of inputs.
|
||||||
|
- **Avalanche effect**
|
||||||
|
A small change in the input should result in a significant change in the hash output, making the new output appear uncorrelated with the old output. This property makes it difficult for attackers to predict the input based on the output or find two different inputs that produce the same output (collision). For example, the SHA-256 hash for `eight` is `c195d2d8756234367242ba7616c5c60369bc25ced2dcb5b92808d31b58ef217a`, but for `right` is `27042f4e6eca7d0b2a7ee4026df2ecfa51d3339e6d122aa099118ecd8563bad9`, despite having only one character different.
|
||||||
|
- **Pseudorandomness**
|
||||||
|
The output of a password hashing algorithm should appear random and uniformly distributed, making it difficult for attackers to predict patterns or relationships between inputs and their corresponding hash outputs.
|
||||||
|
- **Resistance to side-channel attacks**
|
||||||
|
Password hashing algorithms should be designed to resist side-channel attacks, such as timing attacks, where an attacker attempts to gain information about the password or hash by analyzing the time taken to compute the hash.
|
||||||
|
- **Adjustable work factor**
|
||||||
|
A good password hashing algorithm should allow for an adjustable work factor, also known as a cost factor or iteration count. This increases the algorithm's computational complexity over time as hardware capabilities improve, ensuring that the password hashing process remains secure and resource-intensive for attackers.
|
||||||
|
- **Memory hardness**
|
||||||
|
Some modern password hashing algorithms are designed to be memory-hard, meaning that they require a significant amount of memory to compute the hash. This characteristic makes it more difficult for attackers to perform parallel attacks using specialized hardware, such as GPUs or ASICs, which have limited memory resources.
|
||||||
|
- **Wide adoption and peer review**
|
||||||
|
A reliable password hashing algorithm should have a proven track record, be widely adopted, and have undergone extensive peer review and analysis by the cryptographic community. This ensures that the algorithm has been tested for vulnerabilities and is considered secure for password storage and verification.
|
||||||
|
|
||||||
|
## Examples of password-hashing algorithms
|
||||||
|
|
||||||
|
Here are some modern password-hashing algorithms and their concise descriptions:
|
||||||
|
|
||||||
|
- **Bcrypt**
|
||||||
|
Bcrypt is a widely used password hashing algorithm based on the Blowfish cipher. It incorporates a salt and an adjustable work factor to slow down the hashing process, making brute-force attacks more time-consuming. Bcrypt is designed to be resistant to side-channel attacks and is considered secure for password storage.
|
||||||
|
- **Scrypt**
|
||||||
|
Scrypt is a memory-hard password hashing algorithm that requires a significant amount of memory to compute the hash, making it more difficult for attackers to perform parallel attacks using specialized hardware. It also supports adjustable work factors and salt usage. Scrypt was specifically designed to protect against hardware-based attacks, such as those using GPUs or ASICs.
|
||||||
|
- **Argon2**
|
||||||
|
Argon2 is a modern, memory-hard password hashing algorithm that won the Password Hashing Competition in 2015. It offers adjustable work factors for both time (computation) and memory usage, providing a balance between security and performance. Argon2 supports salting and has three main variants:
|
||||||
|
- `Argon2i`: optimized for resistance to side-channel attacks
|
||||||
|
- `Argon2d`: optimized for resistance to time-memory trade-off (TMTO) attacks
|
||||||
|
- `Argon2id`: a hybrid version of both of the above
|
||||||
|
- **PBKDF2 (Password-Based Key Derivation Function 2)**
|
||||||
|
PBKDF2 is a widely-used password hashing algorithm that iteratively applies a pseudorandom function, such as HMAC, to the input password and salt. It supports an adjustable work factor, increasing the number of iterations to make the hashing process slower and more resistant to attacks. While PBKDF2 is considered secure, it is not memory-hard and may be more susceptible to hardware-based attacks compared to `scrypt` or `Argon2`. These modern password hashing algorithms are designed to provide increased security for password storage and verification by incorporating features like salting, adjustable work factors, memory hardness, and resistance to various types of attacks.
|
||||||
|
|
||||||
|
## Password hashing and Appwrite
|
||||||
|
|
||||||
|
Appwrite Authentication also leverages password hashing algorithms to allow developers to secure their users’ passwords via password hashing algorithms. Appwrite uses the `Argon2id` algorithm to hash the password when a user creates an account from a client-side application. Appwrite’s SDKs offer a simple abstraction for the Appwrite Accounts API to let developers implement this, like the following example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Client, Account, ID } from "appwrite";
|
||||||
|
|
||||||
|
const client = new Client()
|
||||||
|
.setEndpoint('https://cloud.appwrite.io/v1')
|
||||||
|
.setProject('<PROJECT_ID>');
|
||||||
|
|
||||||
|
const account = new Account(client);
|
||||||
|
|
||||||
|
const user = await account.create(ID.unique, 'email@example.com', 'password');
|
||||||
|
```
|
||||||
|
|
||||||
|
When a developer implements account creation on a server-side application, however, the Appwrite Users API allows them to input a password that has been hashed using any of the following hashing algorithms:
|
||||||
|
|
||||||
|
- Argon2
|
||||||
|
- Bcrypt
|
||||||
|
- MD5
|
||||||
|
- Scrypt
|
||||||
|
- Scrypt Modified
|
||||||
|
- PHPass
|
||||||
|
- SHA
|
||||||
|
|
||||||
|
An addition side-benefit this offers is that it allows a developer to migrate users from other platforms, such as Firebase, Supabase, and Nhost, using [Appwrite Migrations](https://appwrite.io/docs/advanced/migrations).
|
||||||
|
|
||||||
|
## Recap
|
||||||
|
|
||||||
|
In summary, password hashing algorithms are essential tools for securing sensitive user data, particularly passwords, in modern applications. By understanding these algorithms, developers can make informed decisions when implementing password storage and verification systems. and ensure the security and integrity of their users' data.
|
||||||
|
|
||||||
|
If you want to implement an authentication system that leverages the power of hashing algorithms simply and quickly, try [Appwrite](https://appwrite.io).
|
||||||
BIN
static/images/blog/password-hashing-algorithms.png
Normal file
BIN
static/images/blog/password-hashing-algorithms.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 MiB |
Reference in New Issue
Block a user