Download src/security.py from valent-p/qecho: direct link, hf CLI and curl.
- Browser
- Download file 1.45 kB
-
https://huggingface.co/spaces/valent-p/qecho/resolve/main/src/security.py
- Command line
-
hf download hf://spaces/valent-p/qecho/src/security.py
-
curl -L -o security.py https://huggingface.co/spaces/valent-p/qecho/resolve/main/src/security.py
1.45 kB
| import hashlib | |
| import base64 | |
| import os | |
| from cryptography.fernet import Fernet | |
| from cryptography.hazmat.primitives import hashes | |
| from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC | |
| # --- CORE LOGIC: THE TWIN KEY GENERATOR --- | |
| def generate_keys(group_name: str, password: str) -> tuple[str, str]: | |
| """ | |
| Generates two distinct values from the inputs: | |
| 1. encryption_key: Used to lock/unlock the data (Fernet). | |
| 2. blind_index: Used to find the data in the database. | |
| Why separate them? | |
| If the DB is hacked, they see the 'blind_index'. | |
| They cannot reverse-engineer the 'encryption_key' from the index easily. | |
| """ | |
| # 1. Use the group_name as the Salt. | |
| # This ensures "ProjectX" generates different keys than "ProjectY". | |
| salt = group_name.encode() | |
| # 2. Derive a 32-byte Master Key from the password | |
| kdf = PBKDF2HMAC( | |
| algorithm=hashes.SHA256(), | |
| length=32, | |
| salt=salt, | |
| iterations=100000, | |
| ) | |
| master_key_bytes = kdf.derive(password.encode()) | |
| # 3. Create the Fernet Key (Base64 encoded version of master key) | |
| encryption_key = base64.urlsafe_b64encode(master_key_bytes) | |
| # 4. Create the Blind Index (Hash of the master key) | |
| # We hash the key again so the database admin sees a hash, | |
| # but not the actual key used for decryption. | |
| blind_index = hashlib.sha256(master_key_bytes).hexdigest() | |
| return encryption_key, blind_index | |