uma / psr7-hmac
An HMAC authentication library built on top of the PSR-7 specification
Installs: 43 856
Dependents: 2
Suggesters: 0
Security: 0
Stars: 24
Watchers: 3
Forks: 2
Open Issues: 3
Requires
- php: ^7.3.0 || ^7.4.0 || ^8.0.0
- psr/http-message: ^1.0
- psr/http-server-middleware: ^1.0
Requires (Dev)
- guzzlehttp/psr7: ^1.3
- kambo/httpmessage: ^0.9.0
- laminas/laminas-diactoros: ^2.5
- nyholm/psr7: ^1.0
- phpmetrics/phpmetrics: ^2.7
- phpunit/phpunit: ^9.5
- ringcentral/psr7: ^1.2
- slim/slim: ^3.4
- symfony/psr-http-message-bridge: ^2.0
- wandu/http: ^3.0
- windwalker/http: ^3.1
README
An HMAC authentication library built on top of the PSR-7 specification.
Releases
If you want to build an HMAC-authenticated API based on Symfony check out UMAPsr7HmacBundle, which provides a convenient integration of this library with Symfony's Security Component.
Library API
/** * @param string $secret */ Signer::__construct($secret); /** * @param RequestInterface $request * * @return RequestInterface */ Signer::sign(RequestInterface $request); /** * @param InspectorInterface|null $inspector */ Verifier::__construct(InspectorInterface $inspector = null); /** * @param RequestInterface $request * @param string $secret * * @return bool */ Verifier::verify(RequestInterface $request, $secret);
Demo Script
<?php require_once __DIR__.'/vendor/autoload.php'; use UMA\Psr7Hmac\Signer; use UMA\Psr7Hmac\Verifier; //// CLIENT SIDE $psr7request = new \Zend\Diactoros\Request('http://www.example.com/index.html', 'GET'); // GET /index.html HTTP/1.1 // host: www.example.com $signer = new Signer('secret'); $signedRequest = $signer->sign($psr7request); // GET /index.html HTTP/1.1 // host: www.example.com // authorization: HMAC-SHA256 63IQ8RWDbC9p4ipNrkJz0e0UeGiBrR96zkNdujE5cl8= // signed-headers: host,signed-headers //// SERVER SIDE $verifier = new Verifier(); var_dump($verifier->verify($signedRequest, 'secret')); // true var_dump($verifier->verify($signedRequest, 'another secret')); // false // Headers added after calling sign() do not break the verification, as // they are not included in the signed-headers list. var_dump($verifier->verify($signedRequest->withHeader('User-Agent', 'PHP/5.x'), 'secret')); // true // Changes made to any chunk of data that was present at the time of the // signature are still detected, though. In this example a signed header // is omitted from the Signed-Headers list. var_dump($verifier->verify($signedRequest->withHeader('Signed-Headers', 'host,signed-headers'), 'secret')); // false // The verification also fails if any single part of the request is // removed altogether after signing it. var_dump($verifier->verify($signedRequest->withoutHeader('Signed-Headers'), 'secret')); // false
External Resources
- [PSR-7] HTTP message interfaces
- [RFC 2104] HMAC: Keyed-Hashing for Message Authentication
- [RFC 4231] Identifiers and Test Vectors for HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512
- [RFC 7230] Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
- [RFC 7231] Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
- [RFC 7235] Hypertext Transfer Protocol (HTTP/1.1): Authentication
Disclaimer
The code included in this library has not been reviewed by any cryptographer or security specialist, nor I claim to be one. If you intend to use in your own projects you are advised to read the documentation, understand the code and report back any issues you shall find.