TL;DR
Attaching a secret to a message and hashing it with SHA256 (like sha256(message || secret)) is generally insecure as a MAC. An attacker can often forge signatures without knowing the secret, especially if they can get access to multiple valid message/signature pairs. Use established MAC algorithms like HMAC-SHA256 instead.
Understanding the Problem
The idea behind sha256(message || secret) is simple: you combine the message with a secret key and hash the result. This seems like it should provide authentication – proof that the message hasn’t been tampered with, and that it came from someone who knows the secret.
However, this approach has serious weaknesses. It’s vulnerable to length extension attacks and other forgery techniques.
Why sha256(message || secret) is Insecure
- Length Extension Attacks: SHA256 (and many other hash functions) have a property where knowing the hash of a message, you can compute the hash of
message || padding || another_messagewithout knowing the original message. This means an attacker who sees a valid signature and knows part of the original message can create new valid signatures for different messages. - Collision Vulnerabilities: While SHA256 is collision-resistant, finding collisions (different inputs with the same hash) isn’t impossible. A collision could allow an attacker to forge a signature.
- Lack of Key Derivation: The secret key should be derived from a password or other source using a key derivation function (KDF). Directly concatenating the secret is bad practice.
How Attacks Work (Simplified Example)
Imagine Alice sends Bob sha256(message || secret) as proof of authenticity. An attacker, Mallory, intercepts this.
- Mallory knows the hash value and can figure out the length of the original message (by observing the data).
- Mallory crafts a new message
new_message. - Using techniques exploiting SHA256’s properties, Mallory computes
sha256(original_message || padding || new_message)without knowing the secret. This produces a valid signature fornew_message!
The Solution: Use HMAC-SHA256
HMAC (Hash-based Message Authentication Code) is designed specifically to provide secure message authentication. It uses a secret key and a hash function in a way that prevents the attacks described above.
Steps to Implement HMAC-SHA256
- Choose a Strong Secret Key: The key should be randomly generated and sufficiently long (at least 128 bits).
- Use a Library: Do not implement HMAC yourself. Use a well-vetted cryptography library in your programming language. Examples:
- Python:
hmacmodule - Java:
javax.crypto.Macclass - JavaScript (Node.js):
crypto.createHmac()function
- Python:
- Calculate the HMAC: Use the library to calculate the HMAC of the message with your secret key.
# Python example import hmac hash_message = hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256).hexdigest() - Verify the HMAC: When receiving a message and its HMAC, recalculate the HMAC using your secret key and compare it to the received HMAC.
# Python example import hmac if hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256).hexdigest() == received_hmac: print("Message is authentic!") else: print("Message is forged!")
Key Takeaways
- Never use
sha256(message || secret)as a MAC. It’s insecure. - Always use established MAC algorithms like HMAC-SHA256.
- Use strong, randomly generated secret keys.
- Rely on well-tested cryptography libraries for implementation.

