Skip to content

HMAC Generator — PHP source

Generate a keyed-hash HMAC (SHA-1/256/384/512) for a message and secret. Runs entirely in your browser via Web Crypto, with a shareable link to your exact input.

This is the PHP implementation — the same logic the interactive tool runs, in a shareable, citable form.

<?php
// hmac-generator — PHP polyglot showcase port
//
// Language: PHP
// Ported from: src/lib/hmac.ts
// Display source — part of CosmoDev's polyglot tool pages.
//
// Keyed-hash HMAC via PHP's built-in hash_hmac(), which is backed by the
// system's vetted hashing library (OpenSSL or the bundled hash extension)
// and returns lowercase hex by default — matching the TypeScript reference's
// output format exactly. No extensions or Composer packages are required.
//
// Behavior mirrors the TypeScript reference: UTF-8 inputs, lowercase hex
// output, SHA-256 by default, and rejection of empty secrets and unknown
// algorithms.

declare(strict_types=1);

/*
 * Canonical algorithm names. The spellings match the TypeScript union so the
 * same string works across every port.
 */
const SHA1   = 'SHA-1';
const SHA256 = 'SHA-256'; // default algorithm
const SHA384 = 'SHA-384';
const SHA512 = 'SHA-512';

/**
 * Map a canonical algorithm name to the lowercase form PHP's hash_hmac
 * expects ('sha256', etc.). Returns null for unknown names so the caller can
 * raise a clear error rather than relying on hash_hmac's warning.
 */
function hashAlgoFor(string $algorithm): ?string
{
    switch ($algorithm) {
        case SHA1:
            return 'sha1';
        case SHA256:
            return 'sha256';
        case SHA384:
            return 'sha384';
        case SHA512:
            return 'sha512';
        default:
            return null;
    }
}

/**
 * Compute the HMAC of $message under $secret and return it as lowercase hex.
 *
 * PHP strings are byte strings, so a UTF-8 $message/$secret is forwarded
 * verbatim to hash_hmac — no explicit encoding step is needed. An empty
 * $algorithm selects SHA-256; an empty $secret is rejected: hash_hmac would
 * accept a zero-length key, but the TypeScript reference (SubtleCrypto)
 * refuses one, and matching that contract keeps the ports in parity.
 *
 * @param string $message   The payload to authenticate.
 * @param string $secret    The shared key.
 * @param string $algorithm One of SHA1/SHA256/SHA384/SHA512 (default SHA-256).
 * @return string           Lowercase hex HMAC.
 * @throws InvalidArgumentException On empty secret or unknown algorithm.
 */
function hmac_hex(string $message, string $secret, string $algorithm = SHA256): string
{
    if ($algorithm === '') {
        $algorithm = SHA256;
    }

    $phpAlgo = hashAlgoFor($algorithm);
    if ($phpAlgo === null) {
        throw new InvalidArgumentException("Unsupported HMAC algorithm: {$algorithm}");
    }
    if ($secret === '') {
        throw new InvalidArgumentException('HMAC secret must not be empty');
    }

    // raw_output = false (the default) → lowercase hex string.
    return hash_hmac($phpAlgo, $message, $secret, false);
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →