Quickstart¶
This page provides a quick introduction to HTTP Signatures PHP library and introductory examples.
If you have not already installed HTTP Signatures PHP library head over to the Installation page.
Signing a message¶
Once you have a PSR-7 message ready to send, create a Context with:
- your chosen algorithm
- the list of headers to include in the signature
- the key you will use to sign the message
For these examples we will sign the method + URI (indicated by
(request-target
) and the Content-Type
header. This provides a very
basic level of protection, and you should consider the headers you sign
in your application carefully. These may also be specified by the verifier
(most often a server hosting an API or web service).
Note also that this does not apply only to HTTP requests sent by a client. Servers can add a signature to responses that the client can verify.
Private Key Context (RSA)¶
This type of signature uses a private key known only to you, which can be verified using a public key that is known to anyone who wants to verify the message.
The key file is assumed to be an unencrypted private key in PEM format.
use HttpSignatures\Context;
$context = new Context([
'keys' => ['key43' => file_get_contents('/path/to/privatekeyfile')],
'algorithm' => 'rsa-sha256',
'headers' => ['(request-target)', 'Date', 'Accept'],
]);
Signing the Message:¶
$context->signer()->sign($message);
Now $message contains the Signature
header:
$message->headers->get('Signature');
// keyId="examplekey",algorithm="hmac-sha256",headers="...",signature="..."
Adding a Digest header while signing¶
Include a Digest
header automatically when signing to also protect the
payload (body) of the message in addition to the request-target and headers:
$context->signer()->signWithDigest($message);
$message->headers->get('digest');
// SHA-256=<base64SHA256Digest>
Verifying a Signed Message¶
Most parameters are derived from the Signature in the signed message, so the Context can be created with fewer parameters.
It is probably most useful to create a Context with multilpe keys/certificates. the signature verifier will look up the key using the keyId attribute of the Signature header and use that to validate the signature.
Verifying a HMAC signed message¶
A message signed with an hmac signature is verified using the same key as the one used to sign the original message:
use HttpSignatures\Context;
$context = new HttpSignatures\Context([
'keys' => ['key300' => 'some-other-secret',
'key12' => 'secret-here']
]);
$context->verifier()->isSigned($message); // true or false
Verifying a RSA signed message¶
An RSA signature is verified using the certificate associated with the Private Key that created the message. Create a context by importing the X.509 PEM format certificates in place of the ‘secret’:
use HttpSignatures\Context;
$context = new HttpSignatures\Context([
'keys' => ['key43' => file_get_contents('/path/to/certificate'),
'key87' => $someOtherCertificate],
$context->verifier()->isSigned($message); // true or false
]);
Verifying a message digest¶
To confirm the body has a valid digest header and the header is a valid digest of the message body:
$context->verifier()->isValidDigest($message); // true or false
An all-in-one validation that the signature includes the digest, and the digest is valid for the message body:
$context->verifier()->isSignedWithDigest($message); // true or false
Symfony compatibility¶
Symfony requests normalize query strings which means the resulting request target can be incorrect. See https://github.com/symfony/psr-http-message-bridge/pull/30
When creating PSR-7 requests you use withRequestTarget to ensure the request target is correct. For example
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Component\HttpFoundation\Request;
$symfonyRequest = Request::create('/foo?b=1&a=2');
$psrRequest = (new DiactorosFactory())
->createRequest($symfonyRequest)
->withRequestTarget($symfonyRequest->getRequestUri());