Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # File: hashing_functions.py
- import argon2
- import scrypt
- import bcrypt
- import random
- import string
- import os
- import logging
- import secrets # Added for secure random generation
- from cryptography.fernet import Fernet
- from typing import Optional
- # Configure logging
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
- logger = logging.getLogger(__name__)
- # Function to generate a random salt
- def generate_salt(length: int = 16) -> str:
- salt = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(length))
- logger.info(f'Generated salt: {salt}')
- return salt
- # Function to get the pepper from environment variables
- def get_pepper() -> str:
- pepper_key = os.getenv('PEPPER_KEY')
- if not pepper_key:
- logger.error('PEPPER_KEY environment variable not set.')
- raise EnvironmentError('PEPPER_KEY environment variable not set.')
- fernet = Fernet(pepper_key.encode())
- encrypted_pepper = os.getenv('ENCRYPTED_PEPPER')
- if not encrypted_pepper:
- logger.error('ENCRYPTED_PEPPER environment variable not set.')
- raise EnvironmentError('ENCRYPTED_PEPPER environment variable not set.')
- decrypted_pepper = fernet.decrypt(encrypted_pepper.encode()).decode()
- logger.info('Decrypted pepper successfully.')
- return decrypted_pepper
- # Function to hash password using Argon2id
- def hash_password(password: str, salt: str, pepper: Optional[str] = None) -> str:
- hash_engine = argon2.PasswordHasher(hash_len=64, salt_len=16, time_cost=2, memory_cost=65536, parallelism=8, hash_type=argon2.Type.ID)
- pepper = pepper or get_pepper()
- hashed = hash_engine.hash(password + salt + pepper)
- logger.info('Hashed password successfully.')
- return hashed
- # Function to hash mnemonic code using Argon2id
- def hash_mnemonic_code(mnemonic_code: str, salt: str, pepper: Optional[str] = None) -> str:
- hash_engine = argon2.PasswordHasher(hash_len=32, salt_len=16, time_cost=2, memory_cost=65536, parallelism=8, hash_type=argon2.Type.ID)
- pepper = pepper or get_pepper()
- hashed = hash_engine.hash(mnemonic_code + salt + pepper)
- logger.info('Hashed mnemonic code successfully.')
- return hashed
- # Function to hash PIN using scrypt
- def hash_pin(pin: str, salt: str, pepper: Optional[str] = None) -> bytes:
- pepper = pepper or get_pepper()
- hashed = scrypt.hash(pin + salt + pepper, salt=salt.encode(), N=16384, r=8, p=1)
- logger.info('Hashed PIN successfully.')
- return hashed
- # Function to hash username using bcrypt
- def hash_username(username: str, salt: str, pepper: Optional[str] = None) -> bytes:
- pepper = pepper or get_pepper()
- hashed = bcrypt.hashpw((username + salt + pepper).encode(), bcrypt.gensalt())
- logger.info('Hashed username successfully.')
- return hashed
- # Function to generate a random display name
- def generate_display_name(length: int = 10) -> str:
- display_name = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(length))
- logger.info(f'Generated display name: {display_name}')
- return display_name
- # Example usage
- if __name__ == "__main__":
- password = "P@ssw0rd"
- mnemonic_code = "word1 word2 word3 ..." # 24 words
- pin = "123456789012"
- username = "john_doe"
- display_name = generate_display_name()
- salt_password = generate_salt()
- salt_mnemonic = generate_salt()
- salt_pin = generate_salt()
- salt_username = generate_salt()
- pepper = get_pepper()
- hashed_password = hash_password(password, salt_password, pepper)
- hashed_mnemonic_code = hash_mnemonic_code(mnemonic_code, salt_mnemonic, pepper)
- hashed_pin = hash_pin(pin, salt_pin, pepper)
- hashed_username = hash_username(username, salt_username, pepper)
- print(f"Hashed Password: {hashed_password}")
- print(f"Hashed Mnemonic Code: {hashed_mnemonic_code}")
- print(f"Hashed PIN: {hashed_pin}")
- print(f"Hashed Username: {hashed_username}")
- print(f"Display Name: {display_name}")
- # File: pepper_management.py
- import os
- from cryptography.fernet import Fernet
- import logging
- # Configure logging
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
- logger = logging.getLogger(__name__)
- # Function to retrieve the pepper from environment variables or secrets management service
- def get_pepper() -> str:
- pepper_key = os.getenv('PEPPER_KEY')
- if not pepper_key:
- logger.error('PEPPER_KEY environment variable not set.')
- raise EnvironmentError('PEPPER_KEY environment variable not set.')
- fernet = Fernet(pepper_key.encode())
- encrypted_pepper = os.getenv('ENCRYPTED_PEPPER')
- if not encrypted_pepper:
- logger.error('ENCRYPTED_PEPPER environment variable not set.')
- raise EnvironmentError('ENCRYPTED_PEPPER environment variable not set.')
- decrypted_pepper = fernet.decrypt(encrypted_pepper.encode()).decode()
- logger.info('Decrypted pepper successfully.')
- return decrypted_pepper
- # Example usage
- if __name__ == "__main__":
- try:
- pepper = get_pepper()
- print(f"Pepper: {pepper}")
- except EnvironmentError as e:
- logger.error(f"Error: {e}")
- print(f"Error: {e}")
- # File: test_hashing_functions.py
- import unittest
- from hashing_functions import (
- generate_salt, get_pepper, hash_password, hash_mnemonic_code,
- hash_pin, hash_username, generate_display_name
- )
- import os
- from unittest.mock import patch
- import argon2
- class TestHashingFunctions(unittest.TestCase):
- @patch('hashing_functions.get_pepper', return_value='test_pepper')
- def test_hash_password(self, mock_get_pepper):
- salt = generate_salt()
- hashed = hash_password('password', salt)
- self.assertTrue(isinstance(hashed, str))
- self.assertTrue(hashed.startswith('$argon2id$'))
- @patch('hashing_functions.get_pepper', return_value='test_pepper')
- def test_hash_mnemonic_code(self, mock_get_pepper):
- salt = generate_salt()
- hashed = hash_mnemonic_code('mnemonic_code', salt)
- self.assertTrue(isinstance(hashed, str))
- self.assertTrue(hashed.startswith('$argon2id$'))
- @patch('hashing_functions.get_pepper', return_value='test_pepper')
- def test_hash_pin(self, mock_get_pepper):
- salt = generate_salt()
- hashed = hash_pin('123456', salt)
- self.assertTrue(isinstance(hashed, bytes))
- @patch('hashing_functions.get_pepper', return_value='test_pepper')
- def test_hash_username(self, mock_get_pepper):
- salt = generate_salt()
- hashed = hash_username('username', salt)
- self.assertTrue(isinstance(hashed, bytes))
- def test_generate_salt(self):
- salt = generate_salt()
- self.assertTrue(isinstance(salt, str))
- self.assertEqual(len(salt), 16)
- def test_generate_display_name(self):
- display_name = generate_display_name()
- self.assertTrue(isinstance(display_name, str))
- self.assertEqual(len(display_name), 10)
- if __name__ == "__main__":
- unittest.main()
- # File: test_pepper_management.py
- import unittest
- from unittest.mock import patch
- from pepper_management import get_pepper
- class TestPepperManagement(unittest.TestCase):
- @patch('pepper_management.os.getenv')
- @patch('pepper_management.Fernet.decrypt')
- def test_get_pepper(self, mock_decrypt, mock_getenv):
- mock_getenv.side_effect = lambda key: {
- 'PEPPER_KEY': 'test_pepper_key',
- 'ENCRYPTED_PEPPER': 'test_encrypted_pepper'
- }.get(key)
- mock_decrypt.return_value = b'test_pepper'
- pepper = get_pepper()
- self.assertEqual(pepper, 'test_pepper')
- if __name__ == "__main__":
- unittest.main()
Advertisement
Add Comment
Please, Sign In to add comment