Strong Password Encryption on Local Systems
- מאיר פלג
- Jun 3
- 6 min read
הצפנה חזקה של סיסמאות במערכות מקומיות
סקירה כללית
אחסון סיסמאות באופן מאובטח במחשב מקומי דורש מספר שכבות הגנה. מדריך זה מכסה גישות קריפטוגרפיות מודרניות להצפנה ואחסון של סיסמאות.
עקרונות יסוד
לעולם לא לאחסן סיסמאות בטקסט גלוי
הכלל הבסיסי: סיסמאות לעולם לא צריכות להיות מאוחסנות בצורתן המקורית. אפילו מנהלי מערכת לא צריכים להיות מסוגלים לראות את הסיסמאות האמיתיות.
שימוש בפונקציות חד-כיווניות (האשינג)
במקום הצפנה (שהיא הפיכה), יש להשתמש בפונקציות האש קריפטוגרפיות שקשה מאוד מבחינה חישובית להפוך אותן.
שיטות האשינג מודרניות לסיסמאות
1. bcrypt (מומלץ)
מדוע bcrypt מעולה:
הסתגלותי: יכול להגדיל את הקושי עם הזמן
מלח כלול אוטומטית
נבדק במשך זמן רב ומאומץ באופן נרחב
גורם עבודה מובנה (פרמטר עלות)
איך זה עובד:
משתמש בצופן Blowfish בצורה שונה
יוצר מלח אקראי אוטומטית
גורם עבודה ניתן להתאמה (בדרך כלל 10-12)
פורמט פלט: $2b$[cost]$[22-character salt][31-character hash]
דוגמה לתהליך:
סיסמה: "MySecurePassword123"
מלח: 22 תווים שנוצרו באופן אקראי
עלות: 12 (4096 איטרציות)
תוצאה: $2b$12$N9qo8uLOickgx2ZMRZoMye.IOP3VUK9Qe5QCv6P1uKJz8Xc.L.M4G
2. Argon2 (מתקדם ביותר)
יתרונות:
זוכה תחרות האשינג סיסמאות (2015)
שלושה גרסאות: Argon2d, Argon2i, Argon2id
פונקציה קשה-זיכרון (מתנגדת להתקפות חומרה)
פרמטרי זמן, זיכרון ומקביליות ניתנים להגדרה
Argon2id (גרסה מומלצת):
משלבת את היתרונות של Argon2d ו-Argon2i
עמידה בפני התקפות ערוץ צדדי והתקפות החלפת זמן-זיכרון
פרמטרים:
עלות זמן (איטרציות): 2-3
עלות זיכרון: 64MB-256MB
מקביליות: מספר ליבות CPU
3. scrypt
מאפיינים:
פונקציה קשה-זיכרון
עמידות טובה נגד התקפות חומרה
דרישות זיכרון גבוהות יותר מ-bcrypt
פרמטרים: N (עלות CPU/זיכרון), r (גודל בלוק), p (מקביליות)
שיקולי יישום
יצירת מלח
דרישות:
מחולל מספרים אקראיים קריפטוגרפית מאובטח
מלח ייחודי לכל סיסמה
מינימום 16 בתים (128 ביט)
אחסון מלח לצד האש
כיול גורם עבודה
הנחיות:
התאמה בהתבסס על יכולות החומרה
יעד: זמן חישוב של 250-500 אלפיות שנייה
בדיקה ועדכון קבועים ככל שהחומרה משתפרת
ארכיטקטורת אחסון מאובטח
סכמת מסד נתונים
CREATE TABLE user_credentials (
user_id UUID PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
salt VARCHAR(255) NOT NULL,
hash_algorithm VARCHAR(50) NOT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
גזירת מפתח להצפנת קבצים
PBKDF2 (Password-Based Key Derivation Function 2):
גוזר מפתחות הצפנה מסיסמאות
משתמש ב-HMAC עם SHA-256 או SHA-512
מינימום 100,000 איטרציות (רצוי 600,000+)
דוגמה לשימוש: הצפנת קובץ מסד נתונים סיסמאות מקומי באמצעות סיסמת מאסטר.
שכבות אבטחה נוספות
1. הגנת זיכרון
מחיקת נתונים רגישים מהזיכרון לאחר השימוש
שימוש בהקצאת זיכרון מאובטח כשזמין
מניעת זיכרון dumps המכיל סיסמאות
2. מניעת התקפות טיימינג
שימוש בפונקציות השוואה בזמן קבוע
הימנעות מהחזרות מוקדמות באימות סיסמאות
דוגמה: crypto.timingSafeEqual() ב-Node.js
3. הגבלת קצב
יישום נסיגה אקספוננציאלית לניסיונות כושלים
מנגנוני נעילת חשבון
רישום של פעילות חשודה
4. הצפנה במנוחה
הצפנת דיסק מלא:
BitLocker (Windows)
FileVault (macOS)
LUKS (Linux)
הצפנה ברמת האפליקציה:
הצפנת מסד נתונים סיסמאות עם AES-256
שימוש בהצפנה מאומתת (AES-GCM או ChaCha20-Poly1305)
גזירת מפתח הצפנה מסיסמת מאסטר באמצעות PBKDF2/Argon2
דוגמאות קוד
יישום bcrypt (Python)
import bcrypt
def hash_password(password: str) -> str:
# יצירת מלח והאשינג סיסמה
salt = bcrypt.gensalt(rounds=12)
hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
return hashed.decode('utf-8')
def verify_password(password: str, hashed: str) -> bool:
# אימות סיסמה מול האש
return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8'))
יישום Argon2 (Python)
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
ph = PasswordHasher(
time_cost=3,
memory_cost=65536, # 64MB
parallelism=1,
hash_len=32,
salt_len=16
)
def hash_password(password: str) -> str:
return ph.hash(password)
def verify_password(password: str, hashed: str) -> bool:
try:
ph.verify(hashed, password)
return True
except VerifyMismatchError:
return False
גישת מנהל סיסמאות
ארכיטקטורת מנהל סיסמאות מקומי
סיסמת מאסטר: סיסמה אחת המגנה על כל הכספת
גזירת מפתח: סיסמת מאסטר ← מפתח הצפנה דרך Argon2/PBKDF2
הצפנת כספת: AES-256-GCM עם מפתח נגזר
אפס ידע: אפילו האפליקציה לא יכולה לראות סיסמאות בלי סיסמת מאסטר
מבנה מסד נתונים
קובץ כספת מוצפן:
├── כותרת (גרסה, מידע אלגוריתם)
├── מלח (לגזירת מפתח)
├── IV/Nonce (להצפנה)
├── נתונים מוצפנים (JSON המכיל את כל הסיסמאות)
└── תג אימות (לאימות תקינות)
טעויות נפוצות להימנע מהן
❌ שiטות רעות
שימוש ב-MD5 או SHA-1 לסיסמאות
אי-שימוש במלח (או שימוש באותו מלח לכל הסיסמאות)
אחסון סיסמאות מוצפנות באופן הפיך
שימוש בגורמי עבודה חלשים
יישומי האש מותאמים אישית
✅ שיטות מומלצות
שימוש בספריות מבוססות (bcrypt, Argon2)
יצירת מלחים ייחודיים לכל סיסמה
בדיקות אבטחה ועדכונים קבועים
טיפול נכון בשגיאות ללא דליפת מידע
שיטות פיתוח מאובטחות
שיקולי ביצועים
איזון אבטחה מול ביצועים
אפליקציות אבטחה גבוהה: זמני חישוב ארוכים יותר מקובלים
מערכות עתירות נפח: יכול להיות צורך לאזן אבטחה עם זמן תגובה
אפליקציות מובייל: לקחת בחשבון השפעה על סוללה
בנצ'מרקינג
בדיקת פרמטרים שונים על חומרת היעד:
מדידת זמן חישוב האש
מעקב אחר שימוש בזיכרון
שקילת עומס מקביל
סיכום
הצפנה חזקה של סיסמאות דורשת:
לעולם לא לאחסן סיסמאות בטקסט גלוי
שימוש באלגוריתמי האשינג מודרניים (bcrypt, Argon2)
יישום מליחה נאותה
הגדרת גורמי עבודה מתאימים
הוספת שכבות אבטחה מרובות
בדיקות אבטחה ועדכונים קבועים
המפתח הוא שימוש בספריות קריפטוגרפיות מבוססות במקום יישום פתרונות מותאמים אישית. האשינג סיסמאות מודרני מתוכנן במיוחד להיות איטי וצורך משאבים כדי להפוך התקפות כוח גס לבלתי מעשיות.
Overview
Storing passwords securely on a local computer requires multiple layers of protection. This guide covers modern cryptographic approaches for password encryption and storage.
Core Principles
Never Store Plaintext Passwords
The fundamental rule: passwords should never be stored in their original form. Even system administrators should not be able to see actual passwords.
Use One-Way Functions (Hashing)
Instead of encryption (which is reversible), use cryptographic hash functions that are computationally infeasible to reverse.
Modern Password Hashing Methods
1. bcrypt (Recommended)
Why bcrypt is excellent:
Adaptive: can increase difficulty over time
Salt included automatically
Time-tested and widely adopted
Built-in work factor (cost parameter)
How it works:
Uses the Blowfish cipher in a modified form
Automatically generates random salt
Work factor can be adjusted (typically 10-12)
Output format: $2b$[cost]$[22-character salt][31-character hash]
Example process:
Password: "MySecurePassword123"
Salt: randomly generated 22 characters
Cost: 12 (4096 iterations)
Result: $2b$12$N9qo8uLOickgx2ZMRZoMye.IOP3VUK9Qe5QCv6P1uKJz8Xc.L.M4G
2. Argon2 (State-of-the-Art)
Advantages:
Winner of Password Hashing Competition (2015)
Three variants: Argon2d, Argon2i, Argon2id
Memory-hard function (resists hardware attacks)
Configurable time, memory, and parallelism parameters
Argon2id (recommended variant):
Combines benefits of Argon2d and Argon2i
Resistant to both side-channel and time-memory trade-off attacks
Parameters:
Time cost (iterations): 2-3
Memory cost: 64MB-256MB
Parallelism: number of CPU cores
3. scrypt
Characteristics:
Memory-hard function
Good resistance to hardware attacks
Higher memory requirements than bcrypt
Parameters: N (CPU/memory cost), r (block size), p (parallelization)
Implementation Considerations
Salt Generation
Requirements:
Cryptographically secure random number generator
Unique salt for each password
Minimum 16 bytes (128 bits)
Store salt alongside hash
Work Factor Calibration
Guidelines:
Adjust based on hardware capabilities
Target: 250-500ms computation time
Regular review and updates as hardware improves
Secure Storage Architecture
Database Schema
CREATE TABLE user_credentials (
user_id UUID PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
salt VARCHAR(255) NOT NULL,
hash_algorithm VARCHAR(50) NOT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Key Derivation for File Encryption
PBKDF2 (Password-Based Key Derivation Function 2):
Derives encryption keys from passwords
Uses HMAC with SHA-256 or SHA-512
Minimum 100,000 iterations (preferably 600,000+)
Example use case: Encrypting a local password database file using a master password.
Additional Security Layers
1. Memory Protection
Clear sensitive data from memory after use
Use secure memory allocation when available
Prevent memory dumps containing passwords
2. Timing Attack Prevention
Use constant-time comparison functions
Avoid early returns in password verification
Example: crypto.timingSafeEqual() in Node.js
3. Rate Limiting
Implement exponential backoff for failed attempts
Account lockout mechanisms
Log suspicious activity
4. Encryption at Rest
Full disk encryption:
BitLocker (Windows)
FileVault (macOS)
LUKS (Linux)
Application-level encryption:
Encrypt password database with AES-256
Use authenticated encryption (AES-GCM or ChaCha20-Poly1305)
Derive encryption key from master password using PBKDF2/Argon2
Code Examples
bcrypt Implementation (Python)
import bcrypt
def hash_password(password: str) -> str:
# Generate salt and hash password
salt = bcrypt.gensalt(rounds=12)
hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
return hashed.decode('utf-8')
def verify_password(password: str, hashed: str) -> bool:
# Verify password against hash
return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8'))
Argon2 Implementation (Python)
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
ph = PasswordHasher(
time_cost=3,
memory_cost=65536, # 64MB
parallelism=1,
hash_len=32,
salt_len=16
)
def hash_password(password: str) -> str:
return ph.hash(password)
def verify_password(password: str, hashed: str) -> bool:
try:
ph.verify(hashed, password)
return True
except VerifyMismatchError:
return False
Password Manager Approach
Local Password Manager Architecture
Master Password: Single password protecting entire vault
Key Derivation: Master password → encryption key via Argon2/PBKDF2
Vault Encryption: AES-256-GCM with derived key
Zero-Knowledge: Even the application can't see passwords without master password
Database Structure
Encrypted Vault File:
├── Header (version, algorithm info)
├── Salt (for key derivation)
├── IV/Nonce (for encryption)
├── Encrypted Data (JSON containing all passwords)
└── Authentication Tag (for integrity verification)
Common Mistakes to Avoid
❌ Bad Practices
Using MD5 or SHA-1 for passwords
Not using salt (or using the same salt for all passwords)
Storing passwords reversibly encrypted
Using weak work factors
Custom hash implementations
✅ Best Practices
Use established libraries (bcrypt, Argon2)
Generate unique salts per password
Regular security reviews and updates
Proper error handling without information leakage
Secure development practices
Performance Considerations
Balancing Security vs. Performance
High-security applications: Longer computation times acceptable
High-volume systems: May need to balance security with response time
Mobile applications: Consider battery impact
Benchmarking
Test different parameters on target hardware:
Measure hash computation time
Monitor memory usage
Consider concurrent load
Conclusion
Strong password encryption requires:
Never store plaintext passwords
Use modern hashing algorithms (bcrypt, Argon2)
Implement proper salting
Configure appropriate work factors
Add multiple security layers
Regular security reviews and updates
The key is using well-established cryptographic libraries rather than implementing custom solutions. Modern password hashing is specifically designed to be slow and resource-intensive to make brute-force attacks impractical.
I've created a comprehensive Hebrew explanation of "מליחה" (salting) in cryptography. The explanation covers:
🧂 Key Concepts Explained:
What cryptographic salt is (random data added to passwords)
Why it's called "salt" (cooking metaphor)
How salting works with examples
Why it's critical for security
🛡️ Security Benefits:
Prevents rainbow table attacks
Prevents identical password detection
Slows down brute force attacks
📊 Practical Examples:
Database structure for storing salts
Account creation process
Login authentication process
Code examples showing before/after
⚠️ Common Mistakes:
Using same salt for all passwords
Salt too short
Predictable or non-random salt
Not storing the salt
✅ Best Practices:
Unique salt per password
Random and long enough salt
Proper storage alongside hash
Using established libraries
The explanation shows why…
מה המשמעות של "מליחה" בקריפטוגרפיה?
הגדרה בסיסית
מלח בקריפטוגרפיה הוא נתונים אקראיים שמוסיפים לסיסמה לפני ביצוע האשינג עליה. התהליך נקרא "מליחה".
למה קוראים לזה "מלח"?
המונח מגיע מהבישול - בדיוק כמו שמוסיפים מלח לאוכל כדי לשנות את הטעם, מוסיפים "מלח" קריפטוגרפי לסיסמאות כדי לשנות את פלט האש שלהן.
איך מליחה עובדת:
בלי מלח:
סיסמה: "password123" האש: 482c811da5d5b4bc6d497ffa98491e38
עם מלח:
סיסמה: "password123" מלח: "a1b2c3d4e5f6" משולב: "password123a1b2c3d4e5f6" האש: 7d865e959b2466918c9863afca942d0f
למה מליחה היא קריטית:
1. מונעת התקפות טבלת קשת (Rainbow Table Attacks)
טבלאות קשת הן מסדי נתונים של האשים מחושבים מראש
בלי מלח: התוקף יכול לחפש את האש בטבלת קשת
עם מלח: לכל סיסמה יש האש ייחודי, מה שהופך טבלאות קשת לחסרות תועלת
2. מונעת זיהוי סיסמאות זהות
בלי מלח: אותן סיסמאות = אותם האשים
Great question! "מליחה" (meliha) is the Hebrew translation of "salting" in cryptography. Let me explain what this means:
What is "Salting" (מליחה) in Cryptography?
Salt in cryptography is random data that is added to a password before hashing it. The process is called "salting" (מליחה).
Why is it called "Salt"?
The term comes from cooking - just like you add salt to food to change its taste, you add cryptographic "salt" to passwords to change their hash output.
How Salting Works:
Without Salt:
Password: "password123" Hash: 482c811da5d5b4bc6d497ffa98491e38
With Salt:
Password: "password123" Salt: "a1b2c3d4e5f6" Combined: "password123a1b2c3d4e5f6" Hash: 7d865e959b2466918c9863afca942d0f
Why Salting is Critical:
Prevents Rainbow Table Attacks
Rainbow tables are pre-computed hash databases
Without salt: attacker can look up hash in rainbow table
With…