Question

2.2. Implementation: Create a simple authentication system that includes features such as
password hashing, account lockout mechanisms, and two-factor authentication. Provide
code snippets and explain each feature’s security benefits.

Answers

Answered by GPT-4o mini
Creating a simple authentication system involves implementing features like password hashing, account lockout mechanisms, and two-factor authentication (2FA). Below is a basic outline of how you can implement each feature using Python and Flask, along with explanations of their security benefits. We'll use libraries like `bcrypt` for hashing and `pyotp` for 2FA.

### Set Up

First, make sure to install the necessary libraries:

```bash
pip install Flask Flask-SQLAlchemy bcrypt pyotp Flask-Mail
```

### 1. Password Hashing

Hashing passwords is critical to protect user credentials. Instead of storing plaintext passwords, we store a securely hashed version, making it difficult for attackers to recover the original password.

```python
import bcrypt

def hash_password(password: str) -> bytes:
# Generate a salt and hash the password
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
return hashed_password

def verify_password(stored_password: bytes, provided_password: str) -> bool:
# Check hashed password against a plaintext one
return bcrypt.checkpw(provided_password.encode('utf-8'), stored_password)
```

#### Security Benefit:
- **Data Protection**: Even if the hashed password database is compromised, attackers cannot easily recover the original passwords due to the one-way nature of hashing and the use of salts.

### 2. Account Lockout Mechanism

Account lockouts can help prevent brute force attacks by temporarily locking an account after a specified number of failed login attempts.

```python
from time import time

# Assuming you have a User model
class User:
def __init__(self, username, password_hash):
self.username = username
self.password_hash = password_hash
self.failed_attempts = 0
self.lockout_time = None

def is_locked(self):
if self.lockout_time and (time() - self.lockout_time) < 300: # lockout for 5 minutes
return True
self.failed_attempts = 0 # Reset failed attempts after lockout period
return False

def lock_account(self):
self.lockout_time = time()

def login(user: User, provided_password: str):
if user.is_locked():
return "Account locked. Try again later."

if verify_password(user.password_hash, provided_password):
user.failed_attempts = 0 # Reset on success
return "Login successful!"
else:
user.failed_attempts += 1
if user.failed_attempts >= 5: # lock for 5 failed attempts
user.lock_account()
return "Account locked due to too many failed attempts."
return "Invalid credentials."
```

#### Security Benefit:
- **Brute Force Defense**: By limiting the number of login attempts, it significantly reduces the risk of brute force attacks, making it harder for attackers to gain access.

### 3. Two-Factor Authentication (2FA)

2FA adds an additional layer of security by requiring a second form of verification in addition to the password.

```python
import pyotp
import base64

def generate_2fa_secret():
secret = pyotp.random_base32()
return secret

def get_2fa_uri(username: str, secret: str):
return f"otpauth://totp/{username}?secret={secret}&issuer=MyApp"

def verify_2fa_token(secret: str, token: str) -> bool:
totp = pyotp.TOTP(secret)
return totp.verify(token)
```

To use 2FA in a login process:

```python
def login_with_2fa(user: User, provided_password: str, token: str):
if verify_password(user.password_hash, provided_password):
if verify_2fa_token(user.two_factor_secret, token):
return "Login successful!"
else:
return "Invalid 2FA token."
return "Invalid credentials."
```

#### Security Benefit:
- **Enhanced Security**: Even if a password is compromised, the attacker would still need access to the second factor (e.g., a time-based one-time code), drastically increasing the security of user accounts.

### Conclusion

Combining these features creates a robust authentication mechanism that not only protects user credentials but also adds layers of security to fend off various attack vectors. While no system can guarantee 100% security, implementing these strategies helps mitigate common security threats effectively.

Related Questions