AI is redefining software quality and security. Insights from 450 CISOs & devs →
Aikido

Stop Using MD5 and SHA-1: Modern Hashing for Security

Rule

Don't use outdated hashing algorithms unless contextually justified.

Avoid using outdated hashing algorithms (MD5, SHA-1) in any security-sensitive context. These are cryptographically broken, easy to brute-force, and harm system maintainability.

Supported languages: 45+

Introduction

MD5 and SHA-1 remain widespread in production codebases despite being cryptographically broken for decades. MD5 has been considered insecure since 2004, SHA-1 since 2017. Yet developers continue using them for password hashing, digital signatures, and integrity verification where collision attacks and preimage attacks pose real security risks. The computational cost to generate MD5 collisions is now trivial, and SHA-1 collision attacks are practical with cloud computing resources.

Why it matters

Security implications: MD5 and SHA-1 are vulnerable to collision attacks where two different inputs produce the same hash output. Attackers exploit this to create malicious files with the same hash as legitimate ones, bypassing integrity checks. For password storage, these algorithms are catastrophically weak because they're fast, making brute-force and rainbow table attacks trivial. A modern GPU can compute billions of MD5 hashes per second, meaning an 8-character password can be cracked in hours.

Compliance and legal risk: Security standards like PCI DSS, HIPAA, and SOC 2 explicitly prohibit MD5 and SHA-1 for cryptographic purposes. Using them in regulated environments creates audit failures and legal liability. Major browsers now warn users when encountering SHA-1 certificates, damaging trust and potentially blocking access to your services.

Code maintainability: When outdated hashing algorithms are discovered in code, they require immediate remediation. This creates technical debt that compounds over time because migration becomes harder as more data accumulates. Early adoption of secure algorithms prevents costly future migrations and emergency security patches.

Attack surface expansion: Weak hashing algorithms create multiple attack vectors. Password databases become vulnerable to offline cracking. Digital signatures can be forged. File integrity systems can be bypassed. Each use of MD5 or SHA-1 is a potential security incident waiting to happen.

Code examples

❌ Non-compliant:

const crypto = require('crypto');

function hashPassword(password) {
  return crypto.createHash('md5')
    .update(password)
    .digest('hex');
}

function verifyFileIntegrity(fileContent, expectedHash) {
  const hash = crypto.createHash('sha1')
    .update(fileContent)
    .digest('hex');
  return hash === expectedHash;
}

Why it's unsafe: MD5 for password hashing provides no security against modern cracking tools. SHA-1 for file integrity can be defeated with collision attacks, allowing malicious files to pass verification. Both algorithms are computationally cheap to brute-force.

✅ Compliant:

const crypto = require('crypto');

async function hashPassword(password) {
  const salt = crypto.randomBytes(16);
  return new Promise((resolve, reject) => {
    crypto.pbkdf2(password, salt, 310000, 32, 'sha256', (err, key) => {
      if (err) reject(err);
      resolve({ salt: salt.toString('hex'), hash: key.toString('hex') });
    });
  });
}

function verifyFileIntegrity(fileContent, expectedHash) {
  const hash = crypto.createHash('sha256')
    .update(fileContent)
    .digest('hex');
  return hash === expectedHash;
}

Why it's safe: PBKDF2 with SHA-256 and high iteration count (310,000) makes password cracking exponentially slower. SHA-256 for file integrity is collision-resistant with no known practical attacks. Both algorithms meet current security standards and compliance requirements.

Conclusion

MD5 and SHA-1 have no place in security-sensitive code. Their vulnerabilities are well-documented, exploits are publicly available, and secure alternatives exist in every major language. The migration path is clear: use bcrypt, scrypt, or Argon2 for passwords, and SHA-256 or SHA-3 for integrity verification. Every day these weak algorithms remain in production increases your attack surface.

FAQs

Got Questions?

When is it acceptable to use MD5 or SHA-1?

Only in non-security contexts where collision resistance isn't required: cache keys, ETags for non-sensitive content distribution, or checksums for detecting accidental data corruption (not malicious tampering). Even then, document why the weaker algorithm is acceptable. For any authentication, authorization, integrity verification, or cryptographic signing, these algorithms are never acceptable.

What should I use instead of MD5 and SHA-1 for password hashing?

Use bcrypt, scrypt, or Argon2. These are purpose-built password hashing functions that include salting and are intentionally slow to resist brute-force attacks. Argon2 is the modern standard and won the Password Hashing Competition in 2015. Avoid using general-purpose hash functions like SHA-256 directly for passwords because they're too fast. If you must use SHA-256, wrap it in PBKDF2 with at least 310,000 iterations.

What about SHA-256 or SHA-3 for file integrity?

SHA-256 is currently secure and widely supported. SHA-3 (Keccak) offers even stronger security guarantees with a different internal structure, providing defense-in-depth if SHA-2 is ever broken. For most applications, SHA-256 is sufficient. Use SHA-512 for extra security margin or when working with very large datasets. Both are resistant to known collision and preimage attacks.

How do I migrate existing MD5/SHA-1 hashes without breaking everything?

For passwords, implement dual-hashing during migration: keep old hashes temporarily, but when users log in successfully, rehash their password with the new algorithm and update the database. For API tokens or integrity hashes, version your hash format (e.g., md5:abc123 vs sha256:def456) so systems can handle both during transition. Set a migration deadline and force remaining users to reset after that date.

Are there performance differences between these algorithms?

Yes, but not in ways that matter for security. MD5 is faster than SHA-256, which is exactly the problem for password hashing where slowness is a feature. For file integrity, the performance difference is negligible on modern hardware. SHA-256 adds microseconds to operations that typically involve disk I/O measured in milliseconds. The security benefit vastly outweighs any performance cost.

What about HMAC with MD5 or SHA-1?

HMAC-MD5 and HMAC-SHA-1 are more resistant to attacks than the base hash functions because HMAC provides additional security properties. However, they're still deprecated in most security standards. Use HMAC-SHA-256 instead. The performance difference is minimal and you avoid compliance issues. HMAC-SHA-256 is approved for federal use (FIPS 198-1) and meets all major security standards.

How do I find all instances of MD5/SHA-1 in my codebase?

Search for common patterns: md5, sha1, MessageDigest.getInstance("MD5"), hashlib.md5(), crypto.createHash('md5'). Check dependency configurations for SSL/TLS settings using SHA-1 certificates. Review API integrations with third parties that might require these algorithms. Automated code scanning tools can detect these patterns across multiple languages and flag them for review.

Get secure for free

Secure your code, cloud, and runtime in one central system.
Find and fix vulnerabilities fast automatically.

No credit card required | Scan results in 32secs.