Authentication#

Set up a blockchain account#

The foundation of the whole ecosystem is ADS blockchain. The first step is to set up an account on blockchain. This account will be used for handling incoming and outgoing payments, and sending broadcasts.

The account can be created by the node operator, but more convenient way is ADS wallet browser plugin. Detailed instruction can be found on Setup guide or How to use ADS Wallet page.

After creating an account you will receive an account address, a public key and a secret key.

ADS authentication#

Authentication between servers or modules is performed by sending a signed Authorization header with the ADS account address. Checking the signature allows you to verify the account address and identify the sender.

Authentication header#

ADS account="<string>", nonce="<string>", created="<string>", signature="<string>"
  • account - the ADS account address

  • nonce - a cryptographically random string encoded in Base64

  • created - a datetime in W3C (ISO 8601) format

  • signature - a signature of the nonce and the timestamp from created datetime signed with the the ADS private key

Example:

Authorization: ADS account="0001-00000001-8B4E", nonce="YTVlM2NmZWVlOTBkMzI4NA==", created="2022-10-10T14:42:37+00:00", signature="fd0ae5f6978b6af35a5fff98fc7311a4d56faf5f1b3c6aa13574b631f295934c7af96696b3f7024800dc6e6e4f409dddb4bfcc9d79cf3e07603a8f18e5a62000"

Header signing#

To sign the header you need an ADS account address, the appropriate secret/private key and a sodium library.

To test signatures you can use command line tool.

PHP example code:

$adsAccount = '0001-00000001-8B4E'; // change this
$adsPrivateKey = 'DF7C4188C7F77A182FA7655D5E971863D600A770858804735AFB1B667D2D055A'; // change this

$nonce = random_bytes(32);
$created = new DateTimeImmutable();
$message = $nonce . $created->format('U');
$keyPair = sodium_crypto_sign_seed_keypair(hex2bin($adsPrivateKey));
$secretKey = sodium_crypto_sign_secretkey($keyPair);
$signature = bin2hex(sodium_crypto_sign_detached($message, $secretKey));

$header = sprintf(
    'ADS account="%s", nonce="%s", created="%s", signature="%s"',
    $adsAccount,
    base64_encode($nonce),
    $created->format('c'),
    $signature
);

Header verification#

To verify the signature, you need to validate the account address, get the public key from the ADS blockchain, and use the sodium library.

Additionally, you should verify that the Created header value is valid within five minutes and that the Nonce header value is unique within five minutes.

To test verification you can use command line tool.

PHP example code:

use Adshares\Ads\AdsClient;

$header = $request->headers->get('authorization'); // depends on the framework
$adsClient = new AdsClient(...); // initialize client

$adsRegex = '/ADS account="(?P<account>[^"]+)", nonce="(?P<nonce>[a-zA-Z0-9+\/]+={0,2})", created="(?P<created>[^"]+)", signature="(?P<signature>[^"]+)"/';
if (1 === preg_match($adsRegex, $header, $matches)) {
    $adsAccount = $matches['account'];
    // Check if the account is valid
    $nonce = base64_decode($matches['nonce']);
    // Check if the nonce is not used before
    $created = new DateTimeImmutable($matches['created']);
    // Check if the timestamp is not obsolete
    $signature = $matches['signature'];
    $publicKey = $adsClient->getAccount($adsAccount)->getPublicKey();
    $message = $nonce . $created->format('U');

    $verified = sodium_crypto_sign_verify_detached(hex2bin($signature), $message, hex2bin($publicKey));
}