Skip to content
Cryptography Reviewed 2026-09-12

Weak Hashing Configuration

What does this mean ?

A hashing choice is weak when it fails the security property the application needs. A fast digest, a keyed message authentication code and a password hash solve different problems. Replacing MD5 with SHA-256 does not automatically fix password storage or prove that a message came from a trusted sender.

What can happen ?

Collision-prone digests can undermine integrity checks in security-sensitive protocols. Fast password hashes allow many offline guesses after a database breach. An unkeyed digest sent beside a message can be recomputed by anyone who changes both values.

Recommendation

Purpose Appropriate starting point Important boundary
Compare data against a separately trusted digest SHA-256 or SHA-512 The expected digest needs an independent trust source.
Authenticate a message shared by secret-key holders HMAC with SHA-256 or another approved construction Protect the key and compare tags in constant time.
Store passwords for verification A maintained Argon2id implementation; suitable alternatives include scrypt and policy-approved PBKDF2 Use unique salts, a tuned work factor and the library's verification API.
Encrypt recoverable data A reviewed authenticated-encryption construction Hashing is not encryption; nonce and key handling are separate.

Avoid MD5 and SHA-1 in new security-sensitive digest designs. Do not invent a password hash by repeatedly hashing a string. Bcrypt may remain in legacy systems with an appropriate cost and its byte-length limit understood. Benchmark password verification on deployed hardware and rate-limit requests. SSH is a protocol, not a hash algorithm; there is no blanket reason to disable SSH because a hash configuration is weak.

Sample Code

The first examples compute a digest of non-password data. They show API selection, not an authenticated file-transfer protocol. Each language's data value is already available as bytes or a string as appropriate.

import hashlib
import hmac

# Digest of non-password bytes
digest = hashlib.sha256(data).hexdigest()

# Message authentication; key comes from a managed secret, not source code.
tag = hmac.new(key, data, hashlib.sha256).digest()
valid = hmac.compare_digest(tag, received_tag)
import { createHash } from 'node:crypto';
const digest = createHash('sha256').update(data).digest('hex');

createHash('sha256').update(password) is still an unsuitable password-storage scheme. Use a maintained password-hashing library or an appropriately configured supported KDF.

// Modern .NET, byte[] data. This is not a password hash.
byte[] digest = System.Security.Cryptography.SHA256.HashData(data);

For ASP.NET Core Identity passwords, use its IPasswordHasher<TUser> flow and current configured work factor rather than substituting a raw SHA digest.

byte[] digest = java.security.MessageDigest.getInstance("SHA-256").digest(data);

A raw MessageDigest is not an adaptive password encoder. Use the authentication framework's reviewed password encoder.

// Digest for non-password data
$digest = hash('sha256', $data);

// Password example: requires PHP built with Argon2 support.
$stored = password_hash($password, PASSWORD_ARGON2ID, [
    'memory_cost' => 19456, 'time_cost' => 2, 'threads' => 1
]);
$valid = password_verify($candidatePassword, $stored);

This is a documented baseline configuration; benchmark and raise the cost when practical. The stored hash includes the salt and algorithm parameters. Check password_needs_rehash when policy changes.

import "crypto/sha256"

// data is []byte; use this for non-password data only.
digest := sha256.Sum256(data)

With an existing bcrypt store, bcrypt.GenerateFromPassword(password, cost) requires an explicit cost argument. A missing argument is a compile error, not an example of a weak cryptographic setting. Review bcrypt's 72-byte input boundary.

require 'digest'
digest = Digest::SHA256.hexdigest(data)

Use a maintained authentication/password-hashing library for password verification; a direct Digest call is not a replacement.

Regression checks

For integrity checks, verify a known fixture digest and that a changed byte changes the result. For HMAC, reject a changed message, changed tag and wrong key without logging the key. For password storage, verify the correct password succeeds, an incorrect password fails and two hashes of the same password differ because of salts. Check rehash migration and input-length handling; do not store passwords in test logs.

References