Implementation of secure encryption algorithms for password hashing
import express from 'express';
import crypto from 'crypto';
const app = express();
app.post('/login', (req, res) => {
const { username, password } = req.body;
const hashedPassword = crypto.createHash('md5').update(password).digest('hex');
// Check if the hashed password matches the stored password
if (hashedPassword === '5f4dcc3b5aa765d61d8327deb882cf99') {
res.send('Login successful');
} else {
res.send('Invalid username or password');
}
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The vulnerability in this code is the use of the insecure encryption algorithm MD5 to hash passwords. In the code, the
crypto
module from Node.js is used to create an MD5 hash of the password received from the user during the login process.
The line
const hashedPassword = crypto.createHash('md5').update(password).digest('hex');
creates an MD5 hash of the password by using the
createHash
method with the algorithm set to 'md5'. The
update
method is used to update the hash with the password, and the
digest
method is used to generate the final hash in hexadecimal format.
MD5 is considered insecure for password hashing because it is a fast algorithm and can be easily cracked using precomputed rainbow tables or brute-force attacks. This means that an attacker who gains access to the hashed passwords can easily retrieve the original passwords.
The impact of this vulnerability is that an attacker can potentially crack the captured credentials and gain unauthorized access to user accounts. This can lead to various security risks, such as unauthorized access to sensitive information or impersonation of users.
The recommended solution is to use secure hashing algorithms, such as PBKDF2 (Password-Based Key Derivation Function 2), which are specifically designed for password hashing. PBKDF2 incorporates salting and multiple iterations to make the hashing process slower and more resistant to brute-force attacks.
To fix this vulnerability, the code should be modified to use a secure hashing algorithm like PBKDF2 instead of MD5.
import express from 'express';
import bcrypt from 'bcrypt';
const app = express();
app.use(express.json());
app.post('/login', async (req, res) => {
const { username, password } = req.body;
try {
// Replace the insecure MD5 algorithm with bcrypt
const hashedPassword = await bcrypt.hash(password, 10);
// Check if the hashed password matches the stored password
const isPasswordMatch = await bcrypt.compare(hashedPassword, '5f4dcc3b5aa765d61d8327deb882cf99');
if (isPasswordMatch) {
res.send('Login successful');
} else {
res.send('Invalid username or password');
}
} catch (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The fixed code addresses the vulnerability of using an insecure encryption algorithm (MD5) to hash passwords. It introduces the use of bcrypt, which is a secure hashing algorithm, to store passwords.
Here's how the fixed code works:
1. The code imports the necessary modules, including
express
for creating the web application and
bcrypt
for secure password hashing.
2. The web application is created using
express()
and the
express.json()
middleware is used to parse incoming JSON data.
3. The code defines a POST route
/login
to handle user login requests.
4. Inside the route handler, the username and password are extracted from the request body.
5. The
bcrypt.hash()
function is used to securely hash the password. The function takes two arguments: the password to be hashed and the number of rounds of hashing (in this case, 10). The higher the number of rounds, the more secure the hashing process becomes.
6. The
bcrypt.compare()
function is used to compare the hashed password with the stored password. It takes two arguments: the hashed password and the stored password. If the two passwords match, the function returns
true
, indicating a successful login.
7. Based on the result of the password comparison, the code sends an appropriate response to the client. If the passwords match, the response is "Login successful". Otherwise, the response is "Invalid username or password".
8. Any errors that occur during the process are caught in a try-catch block. If an error occurs, it is logged to the console and a generic error message is sent to the client.
9. The web application listens on port 3000 and logs a message to the console indicating that the server is running.
By using bcrypt to securely hash passwords, the fixed code ensures that even if the password hashes are compromised, it would be extremely difficult for an attacker to reverse-engineer the original passwords.