Get a Pentest and security assessment of your IT network.

Cyber Security

Bcrypt: Safe Key Derivation?

TL;DR

While Bcrypt is excellent for password hashing, it’s not generally recommended as a general-purpose key derivation function (KDF). It’s designed specifically for passwords and has characteristics that make it less suitable for other uses. Use dedicated KDFs like PBKDF2, Argon2, or scrypt instead.

Why Bcrypt is Good

  1. Salted Hashing: Bcrypt automatically adds a random salt to each password before hashing. This prevents rainbow table attacks.
  2. Adaptive Work Factor: You can increase the ‘cost’ parameter (work factor) to make it slower and more computationally expensive, increasing security over time as hardware improves.
  3. Resistance to Brute-Force Attacks: Bcrypt is designed to be slow, making brute-force attacks impractical.

Why Bcrypt Isn’t Ideal for General KDF Use

  1. Password Focus: Bcrypt’s internal workings are optimised for password characteristics (human memorability, common patterns). Other keys might not have these properties.
  2. Limited Configurability: While the cost factor is adjustable, it lacks the flexibility of dedicated KDFs that offer more control over memory usage and iterations.
  3. Potential Side-Channel Attacks: Bcrypt implementations can be vulnerable to side-channel attacks if not carefully implemented (timing attacks). Dedicated KDFs often have better protections built in.
  4. Standardisation: Bcrypt is primarily a password hashing algorithm, and using it for other purposes deviates from established best practices.

Better Alternatives

These are more suitable for deriving keys from secrets:

  • PBKDF2 (Password-Based Key Derivation Function 2): A widely supported and well-understood KDF. It uses a pseudorandom function like HMAC to derive a key from a password and salt.
    python
    import hashlib
    import os
    
    def pbkdf2_hmac(password, salt, iterations=100000, dklen=32):
      dk = hashlib.pbkdf2_hmac('sha256', password, salt, iterations, dklen)
      return dk
    
    salt = os.urandom(16)
    pwd = b'mysecretpassword'
    key = pbkdf2_hmac(pwd, salt)
    print(f"Key: {key.hex()}")
    
  • Argon2: A modern KDF that offers strong security and resistance to various attacks (memory-hard, time-costly). It has different variants (Argon2d, Argon2i, Argon2id) for different use cases.
    python
    import argon2
    
    pwd = b'mysecretpassword'
    hash = argon2.PasswordHasher()
    ph = hash.hash(pwd)
    print(f"Hash: {ph}")
    
  • scrypt: Another memory-hard KDF that is resistant to brute-force attacks.

When *might* Bcrypt be okay?

  1. Legacy Systems: If you have an older system already using Bcrypt for everything and changing it is impractical, it’s better than no protection at all. However, plan to migrate to a dedicated KDF when possible.
  2. Simple Use Cases (Low Security Requirements): For very low-security applications where the key isn’t critical, Bcrypt might be sufficient. But always consider the risks.

Key Takeaway

Use dedicated KDFs like PBKDF2, Argon2, or scrypt for general key derivation. Bcrypt is best reserved for password hashing.

Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation