Vad är en Hash-funktion?
En hash-funktion är en matematisk algoritm som tar input av valfri storlek och producerar en fix-längd output (hash). Det är en “one-way function” - lätt att beräkna framåt, men praktiskt omöjligt att reversera.
Grundläggande egenskaper
1. Deterministisk Samma input ger alltid samma output:
"hello" → 5d41402abc4b2a76b9719d911017c592
"hello" → 5d41402abc4b2a76b9719d911017c592 // Alltid samma
2. Fix längd Oavsett input-storlek, samma output-längd:
MD5("hi") → 49f68a5c8493ec2c0bf489821c21fc3b (32 hex chars)
MD5("hello") → 5d41402abc4b2a76b9719d911017c592 (32 hex chars)
MD5("very long text...") → ... (32 hex chars)
3. Avalanche Effect Minimal förändring i input ger total förändring i output:
MD5("hello") → 5d41402abc4b2a76b9719d911017c592
MD5("hallo") → 4d186321c1a7f0f354b297e8914ab240 // Helt annorlunda!
4. Snabbt att beräkna Hash-funktioner är designade för att vara snabba.
Hash-algoritmer
MD5 (Message Digest 5)
Output: 128 bits (32 hex tecken)
MD5("password") → 5f4dcc3b5aa765d61d8327deb882cf99
Skapad: 1991 av Ronald Rivest
Status: ❌ BRUTEN - Använd INTE för säkerhet
Varför bruten?
- Collision attacks möjliga sedan 2004
- Kan generera två olika inputs med samma hash
- Kan crackas på minuter med modern hårdvara
När kan MD5 fortfarande användas?
// ✅ OK: Non-security checksums
const fileChecksum = md5(fileContent);
// ✅ OK: Cache keys
const cacheKey = md5(url + params);
// ❌ ALDRIG: Lösenord eller säkerhetsrelaterat
const passwordHash = md5(password); // FARLIGT!
SHA-1 (Secure Hash Algorithm 1)
Output: 160 bits (40 hex tecken)
SHA1("password") → 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
Skapad: 1995 av NSA
Status: ❌ DEPRECATED - Fasa ut
Varför deprecated?
- Teoretiska collision attacks 2005
- Praktiska collisions demonstrerade 2017 (SHAttered attack)
- Git använder fortfarande SHA-1 men migrerar till SHA-256
Användning idag:
// ⚠️ Legacy system - fasa ut
if (isLegacySystem) {
hash = sha1(data); // Planera migration till SHA-256
}
// ❌ Nya system - använd INTE
const newHash = sha1(password); // Använd SHA-256+ istället
SHA-256 (SHA-2 family)
Output: 256 bits (64 hex tecken)
SHA256("password") → 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
Skapad: 2001 av NSA
Status: ✅ SÄKER - Rekommenderad
Fördelar:
- Inga kända praktiska attacks
- Används i Bitcoin och blockchain
- NIST standard
- Balans mellan säkerhet och prestanda
Användning:
// ✅ File integrity
const fileHash = sha256(fileContent);
// ✅ Digital signatures
const signature = sign(sha256(message), privateKey);
// ✅ Blockchain
const blockHash = sha256(sha256(blockHeader)); // Bitcoin double-SHA256
// ⚠️ Lösenord - använd bcrypt/argon2 istället
const passwordHash = sha256(password); // OK men bcrypt är bättre
SHA-512 (SHA-2 family)
Output: 512 bits (128 hex tecken)
SHA512("password") → b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
Skapad: 2001 av NSA
Status: ✅ SÄKER - Extra stark
Fördelar:
- Starkare säkerhet än SHA-256
- Snabbare på 64-bit system
- Större hash = mindre risk för collisions
Nackdelar:
- Dubbelt så lång output
- Långsammare på 32-bit system
- Ofta overkill för de flesta use cases
När använda SHA-512:
// ✅ Extra känslig data
const topSecretHash = sha512(sensitiveData);
// ✅ Long-term arkivering
const archiveHash = sha512(document);
// ✅ HMAC för tokens
const token = hmacSha512(data, secretKey);
// ❌ När storlek spelar roll (URLs, databaser)
const shortHash = sha256(data); // Bättre val
SHA-3 (Keccak)
Output: Variabel (224, 256, 384, 512 bits)
Skapad: 2015 (NIST competition vinnare)
Status: ✅ SÄKER - Ny standard
Skillnader från SHA-2:
- Helt annan intern struktur (sponge construction)
- Inte baserad på Merkle-Damgård
- Teoretiskt mer motståndskraftig mot vissa attacks
Användning:
// ✅ När SHA-2 inte är tillräckligt
const futureProofHash = sha3_256(data);
// ✅ Ethereum använder Keccak256
const ethereumHash = keccak256(data);
Varför inte mer populär?
- SHA-256 är fortfarande säker
- SHA-3 är långsammare i många implementationer
- Mindre ecosystem support
Jämförelse
| Algorithm | Output Size | Speed | Security | Use Case |
|---|---|---|---|---|
| MD5 | 128 bit | ⚡⚡⚡ Snabbast | ❌ Bruten | Checksums (non-security) |
| SHA-1 | 160 bit | ⚡⚡ Snabb | ⚠️ Deprecated | Legacy, Git |
| SHA-256 | 256 bit | ⚡ Medium | ✅ Säker | Rekommenderad standard |
| SHA-512 | 512 bit | ⚡ Medium | ✅ Mycket säker | Extra säkerhet |
| SHA-3 | Variabel | 🐌 Långsammare | ✅ Framtidssäker | Nya system |
Praktiska exempel
1. File Integrity Check
// Ladda ner fil och verifiera integritet
async function downloadAndVerify(url, expectedHash) {
const response = await fetch(url);
const buffer = await response.arrayBuffer();
const hash = await crypto.subtle.digest('SHA-256', buffer);
const hashHex = Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
if (hashHex !== expectedHash) {
throw new Error('File integrity check failed!');
}
return buffer;
}
// Användning
await downloadAndVerify(
'https://example.com/file.zip',
'abc123...' // SHA-256 hash från källan
);
2. Git Commit Hash
# Git använder SHA-1 (migrerar till SHA-256)
git log --oneline
# a1b2c3d Fix bug in login
# e4f5g6h Add new feature
# Commit hash är SHA-1 av:
# - Tree hash
# - Parent commit hash
# - Author info
# - Commit message
# - Timestamp
3. Bitcoin Mining
// Bitcoin mining = hitta hash som börjar med nollor
function mine(blockHeader, difficulty) {
let nonce = 0;
const target = '0'.repeat(difficulty);
while (true) {
const hash = sha256(sha256(blockHeader + nonce));
if (hash.startsWith(target)) {
return { nonce, hash };
}
nonce++;
}
}
// Hitta hash som börjar med 4 nollor
const result = mine("Block data...", 4);
// { nonce: 182394, hash: "0000abc123..." }
4. Password Verification (DÅLIG METOD)
// ❌ ANVÄND ALDRIG SHA för lösenord direkt!
function badPasswordHash(password) {
return sha256(password);
}
// Problem:
// 1. För snabbt - 1 miljard försök per sekund
// 2. Rainbow tables
// 3. Ingen salt
// ✅ Använd istället bcrypt/argon2
import bcrypt from 'bcrypt';
async function goodPasswordHash(password) {
const salt = await bcrypt.genSalt(12);
return await bcrypt.hash(password, salt);
}
5. Cache Keys
// ✅ Bra användning av SHA-256 för cache
function getCacheKey(url, params) {
const data = JSON.stringify({ url, params });
return sha256(data);
}
const cacheKey = getCacheKey(
'/api/users',
{ page: 1, limit: 10 }
);
// "a1b2c3d4..."
cache.get(cacheKey);
Hash vs Encryption
| Hash | Encryption |
|---|---|
| One-way | Two-way |
| Fix output size | Variabel output |
| Snabb | Långsammare |
| Deterministisk | Använder keys |
| Integrity check | Confidentiality |
Hash:
const hash = sha256("secret");
// "2bb80..."
// Kan INTE återfås till "secret"
Encryption:
const encrypted = encrypt("secret", key);
// "x7j9k..."
const decrypted = decrypt(encrypted, key);
// "secret" ✅ Kan dekrypteras
HMAC (Hash-based Message Authentication Code)
Kombinerar hash med en secret key:
function hmac(message, secretKey) {
const hash1 = sha256((secretKey ^ opad) + sha256((secretKey ^ ipad) + message));
return hash1;
}
// Verifierar både integritet OCH autenticitet
const signature = hmac("message", "secret-key");
Användning:
- JWT tokens
- API signatures (AWS, etc.)
- Webhook verification
// Verifiera webhook från GitHub
const signature = req.headers['x-hub-signature-256'];
const payload = req.body;
const secret = process.env.WEBHOOK_SECRET;
const expectedSignature = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
if (signature !== expectedSignature) {
throw new Error('Invalid signature');
}
Rainbow Tables & Salt
Problem:
// Samma lösenord = samma hash
sha256("password123") → "ef92b..."
sha256("password123") → "ef92b..." // Samma!
// Rainbow table: förberäknade hashar
// "password123" → "ef92b..."
// "123456" → "8d969..."
// ...millions more...
Lösning: Salt
// Lägg till random data innan hash
const salt = generateRandomBytes(16);
const hash = sha256(password + salt);
// Spara både salt och hash
db.save({
salt: salt,
hash: hash
});
// Nu är samma lösenord olika hash
sha256("password123" + "abc") → "123..."
sha256("password123" + "xyz") → "789..." // Olika!
Därför: Använd bcrypt som gör detta automatiskt!
Välja rätt algoritm
För File Integrity
✅ SHA-256 // Bästa balansen
✅ SHA-512 // Extra paranoid
❌ MD5 // Bara för non-security
För Lösenord
✅ bcrypt // Rekommenderad
✅ argon2 // Modernare, starkare
✅ scrypt // Också bra
❌ SHA-256 // För snabbt, ingen salt management
❌ MD5 // ALDRIG!
För Digital Signatures
✅ SHA-256 // Standard
✅ SHA-512 // Extra säkerhet
✅ SHA-3 // Framtidssäker
För Git/Blockchain
✅ SHA-256 // Bitcoin, modern Git
⚠️ SHA-1 // Legacy Git (migrerar)
För Cache Keys
✅ SHA-256 // Bra balans
✅ MD5 // OK för cache
✅ SHA-1 // OK för cache
Performance
Benchmark (1 miljard operationer):
MD5: ~2 sekunder ⚡⚡⚡
SHA-1: ~3 sekunder ⚡⚡
SHA-256: ~4 sekunder ⚡
SHA-512: ~3 sekunder ⚡ (på 64-bit)
SHA-3: ~6 sekunder 🐌
För de flesta applikationer spelar hastigheten ingen roll!
Security Best Practices
1. Använd rätt verktyg
// ❌ Fel verktyg
const passwordHash = md5(password);
// ✅ Rätt verktyg
const passwordHash = await bcrypt.hash(password, 12);
2. Håll dig uppdaterad
// ⚠️ Fasas ut
if (usingLegacySHA1) {
planMigrationToSHA256();
}
3. Kombinera med salt
// ❌ Utan salt
const hash = sha256(password);
// ✅ Med salt
const salt = crypto.randomBytes(16);
const hash = sha256(password + salt);
4. Iterera för lösenord
// ❌ En iteration
const hash = sha256(password);
// ✅ Många iterationer (bcrypt gör detta)
let hash = password;
for (let i = 0; i < 10000; i++) {
hash = sha256(hash);
}
Verktyg
Testa olika hash-algoritmer:
- Hash Generator - Testa MD5, SHA-1, SHA-256, SHA-512
- Bcrypt Generator - Säker lösenordshashing
- Password Strength Checker - Validera lösenordsstyrka
Slutsats
För nya projekt:
- ✅ SHA-256 - Standard för file integrity, signatures
- ✅ bcrypt/argon2 - ALLTID för lösenord
- ✅ HMAC-SHA256 - För authentication tokens
Undvik:
- ❌ MD5 - Endast non-security use cases
- ❌ SHA-1 - Fasas ut, planera migration
- ❌ SHA-256 för lösenord - Använd bcrypt istället
Kom ihåg: Hash ≠ Encryption ≠ Encoding
Välj rätt verktyg för jobbet!