Skip to content

Latest commit

 

History

History
154 lines (108 loc) · 4.7 KB

Class_PublicKeyMethod.md

File metadata and controls

154 lines (108 loc) · 4.7 KB

PublicKeyMethod Class

Authentication method using public/private client keys.

This method is similar to the DefaultAuthenticationMethod in that it will add a random X-Request-ID header (if missing) which will also be checked by the verify() method.

It also has the client identification string in the X-API-Client header.

It has however no X-API-Token header. It has the X-API-Signature header instead which contains a cryptographic signature calculated using the client's private key and verified using the client's public key.

This means that the KeyRepository supplied to verify() must return the client's public key. The client's private key should not be stored on the server side at all.

This method assumes that the paragonie/halite cryptographic library is available in your project.

Requirements

Using this class requires the paragonie/halite library and the libsodium extension (it's a core PHP module starting with PHP 7.2).

composer require paragonie/halite

Class Details

Constructor

  • __construct ()

Using Public and Private Keys

The library includes the HaliteSigningPublicKey and HaliteSigningPrivateKey wrapper classes. They're used internally and for key pair generation.

To generate a new key pair, use the HaliteSigningPrivateKey::generate() constructor:

<?php
use mle86\RequestAuthentication\Crypto\Halite\HaliteSigningPrivateKey;
use mle86\RequestAuthentication\Crypto\Halite\HaliteSigningPublicKey;

$privateKey = HaliteSigningPrivateKey::generate();                 // instanceof HaliteSigningPrivateKey
$publicKey  = HaliteSigningPublicKey::fromPrivateKey($privateKey); // instanceof HaliteSigningPublicKey

$encodedPrivateKey = $privateKey->getEncodedForm(); // printable string
$encodedPublicKey  = $publicKey->getEncodedForm();  // printable string

The encoded private key should be stored on the client side only. It's needed to authenticate outbound requests.

The encoded public key should be stored on the server side in the KeyRepository that will be used later for request verification.

The encoded form returned by getEncodedForm() is a printable string without whitespace. It is the only key form that will be used later, the HaliteSigningPublicKey/HaliteSigningPrivateKey wrapper classes won't be used directly.

Authenticating and Verifying Requests

To authenticate an outbound request, the encoded form of a HaliteSigningPrivateKey is needed. (This is a string that should be sent to the client once after generating a new public/private key pair. It should not be stored on the server side, as that would defeat the purpose of public/private cryptography.)

<?php
use mle86\RequestAuthentication\RequestAuthenticator;
use mle86\RequestAuthentication\AuthenticationMethod\PublicKeyMethod;

$clientId          = …;
$encodedPrivateKey = …;
$request           = …;

$authenticator = new RequestAuthenticator(
    new PublicKeyMethod,
    $clientId,
    $encodedPrivateKey);

$authenticatedRequest = $authenticator->authenticate($request);

To verify an inbound request, a KeyRepository that returns the client's encoded public key is needed.

<?php
use mle86\RequestAuthentication\RequestVerifier;
use mle86\RequestAuthentication\KeyRepository\ArrayRepository;
use mle86\RequestAuthentication\AuthenticationMethod\PublicKeyMethod;

$clientId         = …;
$encodedPublicKey = …;
$inboundRequest   = …;

$keys = new ArrayRepository([
    $clientId => $encodedPublicKey,
]);

$verifier = new RequestVerifier(
    new PublicKeyMethod,
    $keys);

$verifier->verify($inboundRequest);

Extra Methods

  • generateRequestId (): string
    Generates a random hex request ID. This is used in authenticate() to auto-generate the X-Request-ID header value if the request does not have one yet.