Skip to main content

Message API

Authentication

Authentication is implemented by signing a request using ECDSA algorithm.

Generate Private and Public Keys

Your private key is used to sign your authentication requests. Run this command to create your private key:

openssl ecparam -name prime256v1 -genkey -out private.pem

Use private key to generate a public key:

openssl ec -in private.pem -pubout -out public.pem

The result of these commands will be two files:

private.pem example

-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICANhwl1a8C7PDQE+BBBY1nr6RPIBxcp461EyBU7k5WzoAoGCCqGSM49
AwEHoUQDQgAEdVgfFzlM6jT2okGwtM65Cl091OUTA7+bTj2nRmyIsU33TQeq15pn
hTz7nk3rJK+p/hCsk/mHdEAMGsb/4cKqkA==
-----END EC PRIVATE KEY-----

You should leave only this part:

MHcCAQEEICANhwl1a8C7PDQE+BBBY1nr6RPIBxcp461EyBU7k5WzoAoGCCqGSM49
AwEHoUQDQgAEdVgfFzlM6jT2okGwtM65Cl091OUTA7+bTj2nRmyIsU33TQeq15pn
hTz7nk3rJK+p/hCsk/mHdEAMGsb/4cKqkA==

public.pem example

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdVgfFzlM6jT2okGwtM65Cl091OUT
A7+bTj2nRmyIsU33TQeq15pnhTz7nk3rJK+p/hCsk/mHdEAMGsb/4cKqkA==
-----END PUBLIC KEY-----

For authentication use Authorization Header like:

Authorization: s1mpl signature <identity> <alg> <data>
  • identity - user/service (provided be vendor)
  • alg - signature algorithm (for project es256)
  • data - byte array of signature data (base64):
    • timestamp - 8 bytes, UTC time of sending the HTTP request
    • request id - 16 bytes, request's GUID, new for each request
    • signature - remaining bytes (the number depends on the algorithm), a digital signature of the previous bytes

Signing examples

private static readonly byte[] PrivateKey = Convert.FromBase64String(@"MHcCAQEEICANhwl1a8C7PDQE+BBBY1nr6RPIBxcp461EyBU7k5WzoAoGCCqGSM49AwEHoUQDQgAEdVgfFzlM6jT2okGwtM65Cl091OUTA7+bTj2nRmyIsU33TQeq15pnhTz7nk3rJK+p/hCsk/mHdEAMGsb/4cKqkA==");

private static async Task Main(string[] args)
{
var client = new HttpClient();

var url = string.Format(BaseUrl, "queue?take=100");

var request = new HttpRequestMessage(HttpMethod.Get, url);

var sign = CreateSignature();

request.Headers.Add("Authorization", $"s1mpl signature some-service es256 { Convert.ToBase64String(sign) }");

var response = await client.SendAsync(request);

Console.ReadLine();
}

private static byte[] CreateSignature()
{
var alg = ECDsa.Create();

if (alg == null)
throw new InvalidOperationException("No signature algorithm implementation available");

var signingData = BitConverter.GetBytes(DateTime.UtcNow.Ticks)
.Concat(Guid.NewGuid().ToByteArray())
.ToArray();

alg.ImportECPrivateKey(PrivateKey, out _);

var signature = alg.SignData(signingData, HashAlgorithmName.SHA256);

return signingData.Concat(signature).ToArray();
}