A basic user management system in Python with plain-text password storage evolves into a more secure implementation using SHA-256 hashing. Below is the initial structure in Python, followed by a Java equivalent with enhanced security.
# Initial Python implementation with plain-text passwords
class User:
def __init__(self, name, password):
self.name = name
self.password = password
users = []
def add_user(name, password):
new_user = User(name, password)
users.append(new_user)
print(f"User {name} added successfully.")
def login(username, password):
for user in users:
if user.name == username and user.password == password:
print("Login successful!")
return True
print("Incorrect username or password.")
return False
# Main loop
while True:
print("\nWelcome to User Management System")
print("1. Add User")
print("2. Login")
print("3. Exit")
choice = input("Select an option (1/2/3): ")
if choice == "1":
name = input("Username: ")
password = input("Password: ")
add_user(name, password)
elif choice == "2":
username = input("Username: ")
password = input("Password: ")
login(username, password)
elif choice == "3":
print("Goodbye!")
break
else:
print("Invalid choice, try again.")
The plain-text approach is insecure. Passwords should be hashed before storage using a cryptographic hash function like SHA-256. The enhanced Python version uses the hashlib library.
# Enhanced Python implementation with SHA-256 hashing
import hashlib
class User:
def __init__(self, name, password):
self.name = name
self.password = self._encrypt_password(password)
def _encrypt_password(self, password):
sha256 = hashlib.sha256()
sha256.update(password.encode('utf-8'))
return sha256.hexdigest()
users = []
def add_user(name, password):
new_user = User(name, password)
users.append(new_user)
print(f"User {name} added successfully.")
def login(username, password):
for user in users:
if user.name == username and user.password == User(username, password).password:
print("Login successful!")
return True
print("Incorrect username or password.")
return False
# Main loop remains the same
Now, the same functionality implemented in Java using MessageDigest for SHA-256 hashing:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class User {
private String name;
private String passwordHash;
public User(String name, String password) {
this.name = name;
this.passwordHash = encryptPassword(password);
}
private String encryptPassword(String password) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(password.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-256 not available", e);
}
}
public String getName() { return name; }
public String getPasswordHash() { return passwordHash; }
}
public class UserSystem {
private static List<User> users = new ArrayList<>();
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
while (true) {
System.out.println("\nWelcome to User Management System");
System.out.println("1. Add User");
System.out.println("2. Login");
System.out.println("3. Exit");
System.out.print("Select an option (1/2/3): ");
String choice = scanner.nextLine();
switch (choice) {
case "1":
addUser();
break;
case "2":
login();
break;
case "3":
System.out.println("Goodbye!");
return;
default:
System.out.println("Invalid choice, try again.");
}
}
}
private static void addUser() {
System.out.print("Username: ");
String name = scanner.nextLine();
System.out.print("Password: ");
String password = scanner.nextLine();
User newUser = new User(name, password);
users.add(newUser);
System.out.println("User " + name + " added successfully.");
}
private static void login() {
System.out.print("Username: ");
String username = scanner.nextLine();
System.out.print("Password: ");
String password = scanner.nextLine();
String inputHash = new User(username, password).getPasswordHash();
for (User u : users) {
if (u.getName().equals(username) && u.getPasswordHash().equals(inputHash)) {
System.out.println("Login successful!");
return;
}
}
System.out.println("Incorrect username or password.");
}
}
The Java version replicates the same logic: during registration, a SHA-256 hash is computed and stored; during login, the provided password is hashed and compared with the stored hash. No plain-text passwords are kept.
For production systems, consider adding salt to each password hash to prevent rainbow table attacks: generate a random salt per user, store it alongsidee the hash, and compute SHA-256(salt + password).