How to Use PHP hash_hmac for Authentication
This article explains how the hash_hmac() function
provides cryptographic message authentication in PHP. You will learn the
mechanics behind Keyed-Hash Message Authentication Codes (HMAC), the
syntax of the PHP function, why it is superior to simple hashing for
security, and how to implement and verify HMACs securely in your
applications.
What is hash_hmac()?
The hash_hmac() function in PHP is used to generate a
Keyed-Hash Message Authentication Code (HMAC). An HMAC is a specific
type of message authentication code that involves a cryptographic hash
function in combination with a secret cryptographic key.
By combining the message data with a secret key,
hash_hmac() ensures both data integrity
(proving the message has not been altered) and
authenticity (proving the message was sent by someone
who possesses the secret key).
How hash_hmac() Works
When you hash a message using a standard hashing function like
sha256, anyone can intercept the message, alter it, and
recalculate the hash.
The hash_hmac() function prevents this by incorporating
a shared secret key into the hashing process. The calculation is done in
two passes: 1. The secret key is mixed with the message, and the result
is hashed. 2. The inner hash is mixed with the key again and hashed a
second time.
This two-step process makes it computationally impossible for an attacker to alter the message and generate a valid hash without knowing the secret key, even if they know the hashing algorithm used. It also protects against length extension attacks, which standard hashing algorithms like SHA-256 are vulnerable to when used naively for authentication.
Syntax and Parameters
The syntax for the function is:
hash_hmac(string $algo, string $data, string $key, bool $binary = false): string$algo: The name of the selected hashing algorithm (e.g.,"sha256","sha512","md5"). For security purposes,"sha256"or higher is recommended.$data: The input message or payload to be hashed.$key: The shared secret key used to generate the HMAC. This key should be kept secure and never exposed publicly.$binary: When set totrue, the function outputs raw binary data. When set tofalse(default), it outputs a lowercase hex string.
Practical Code Example
Below is a simple implementation of generating an HMAC signature for an API request payload.
// The payload to be sent
$message = "action=transfer&amount=100&recipient=user123";
// A strong, shared secret key
$secretKey = "super-secure-shared-secret-key";
// Generate the HMAC signature using SHA-256
$signature = hash_hmac('sha256', $message, $secretKey);
echo "Payload: " . $message . "\n";
echo "Signature: " . $signature;Verifying the HMAC Safely
To verify the message on the receiving end, the receiver recalculates the HMAC using the same secret key and the received message, then compares it to the sent signature.
To prevent timing attacks (where an attacker can
guess the signature character-by-character based on how long the
comparison takes), you must use PHP’s hash_equals()
function for the comparison instead of the standard == or
=== operators.
// Received payload and signature
$receivedMessage = "action=transfer&amount=100&recipient=user123";
$receivedSignature = "the-signature-sent-by-sender";
// Recalculate the expected signature
$expectedSignature = hash_hmac('sha256', $receivedMessage, $secretKey);
// Securely compare the signatures
if (hash_equals($expectedSignature, $receivedSignature)) {
echo "Message is authentic and untampered.";
} else {
echo "Authentication failed. Invalid signature.";
}By utilizing hash_hmac() paired with
hash_equals(), PHP developers can easily implement secure,
tamper-proof message transport systems, API authentication, and secure
token verification.