Site Authorization Ticket

Generation algorithm

To generate a ticket, follow these steps:

  • Generate a message. Message content depends on ticket type:
    External ID ticket
    Email address ticket
    Mobile number ticket
    Message types are described below depending on ticket type.
  • Calculate message hash using the hmac algorithm (check the secret key, or salt, with the manager). Use sha512 as the hashing algorithm for hmac.
  • Translate the message and its hash into HEX strings. Use UTF-8 to translate the message into a byte array. Important: If hashing library returns hash as a HEX string, there's no need to encode it as HEX again.
  • Combine the strings with an "|": |.
  • MyWebSite is the name of client ID type.
string secretKey = "PUT_YOUR_SECRET_KEY_HERE"

string myWebSiteId = "1543"

DateTime dateTime = GetCurrentDateTime()
string dateTimeString = dateTime.ToString("yyyy-MM-dd HH:mm:ss")

string message = "ExternalIdentityAuthentication|MyWebSite|" + myWebSiteId + "|" + dateTimeString 
byte[] messageBytes = StringToBytesInUTF8(message)

byte[] hash = hmacSha512(messageBytes, secretKey)

string messageHexString = ByteArrayToHexString(messageBytes)
string hashHexString = ByteArrayToHexString(hash)

string result = messageHexString + "|" + hashHexString
$secretKey = 'PUT_YOUR_SECRET_KEY_HERE';

$myWebSiteId = 'PUT_CUSTOMER_ID_HERE';
$dateTimeString = gmdate('Y-m-d H:i:s');

$message = 'ExternalIdentityAuthentication|MyWebSite|'.$myWebSiteId.'|'.$dateTimeString;
$hash = hash_hmac('sha512', $message, $secretKey);

$result = bin2hex($message).'|'.$hash;

Ticket Verification Algorithm

To verify a ticket, follow these steps:

  • Split the ticket in two by "|". First part is the message, second one its hash.
  • Translate the message from HEX string into a byte array using UTF-8.
  • Calculate message hash using the hmac algorithm (check the secret key, or salt, with the manager). Use sha512 as the hashing algorithm for hmac.
  • Compare calculated hash to ticket hash value. If they don't match, the ticket is invalid.
  • Split the message by "|". Verify each part.
  • [Optional] Compare ticket date to current date. If ticket is too old, it can be considered expired. Ticket expiry term is arbitrary (you can even skip this check).
string secretKey = "PUT_YOUR_SECRET_KEY_HERE"

string ticket = "PUT_TICKET_HERE"

string[] ticketParts = ticket.split("|")

byte[] messageBytes = HexStringToByteArray(ticketParts[0])
byte[] hash = HexStringToByteArray(ticketParts[1])

byte[] realHash = hmacSha512(messageBytes, secretKey)

if (realHash != hash)
{
  throw new Exception("Incorrect hash")
}
else
{
  string message = BytesInUTF8ToString(messageBytes)
  string[] messageParts = ticket.split(message)
  string ticketType = messageParts[0];
  
  if (ticketType != "ExternalIdentityAuthentication")
  {
    throw new Exception("Unknown ticket type " + ticketType);
  }
  if (messageParts.Count != 4)
  {
    throw new Exception("There should be 4 messageParts.");
  }
  
  string identityType = messageParts[1];
  if (identityType != "MyWebSite")
  {
    throw new Exception("Unknown identity " + identityType);
  }
  
  string identity = messageParts[2];
  DateTime creationDateTimeUtc = ParseDateTime(messageParts[3], "yyyy-MM-dd HH:mm:ss");
  
  // If needed, you can compare creationDateTimeUtc to current UTC time and ignore the ticket if it's too old
}
$secretKey = 'PUT_YOUR_SECRET_KEY_HERE';

$ticket = 'PUT_TICKET_HERE';

$ticketParts = explode('|', $ticket);

$message = hex2bin($ticketParts[0]);
$hash = $ticketParts[1];

$realHash = hash_hmac('sha512', $message, $secretKey);

if ($realHash != strtolower($hash))
{
  throw new Exception('Incorrect hash');
}
else
{
  $messageParts = explode('|', $message);
  $ticketType = $messageParts[0];
  
  if ($ticketType != 'ExternalIdentityAuthentication')
  {
    throw new Exception('Unknown ticket type '.$ticketType);
  }
  if (count($messageParts) != 4)
  {
    throw new Exception('There should be 4 messageParts.');
  }
  
  $identityType = $messageParts[1];
  if ($identityType != 'MyWebSite')
  {
    throw new Exception('Unknown identity '.$identityType);
  }
  
  $identity = $messageParts[2];
  $creationDateTimeUtc = date_create_from_format('Y-m-d H:i:s', $messageParts[3]);
  
  // If needed, you can compare $creationDateTimeUtc to current UTC time and ignore the ticket if it's too old
}

Message for External ID Ticket

The message is formatted as follows:
ExternalIdentityAuthentication|||<*date and time in UTC+0 as yyyy-MM-dd HH:mm:ss>.

  • Here externalIdentitySystemName is the name of the field that stores the site customer ID in directCrm; it is set up via Maestra framework.
  • Ticket is considered valid for half an hour from date and time specified in it.

Example:
ExternalIdentityAuthentication|MyWebSite|1543|2015-12-10 09:12:25

Message for Email Address Ticket

The message is formatted as follows:
EmailAuthenticationHex||<*date and time in UTC+0 as yyyy-MM-dd HH:mm:ss>

  • Ticket is considered valid for half an hour from date and time specified in it.

Example:
EmailAuthenticationHex|[email protected]|2015-12-10 09:12:25

Message for Mobile Number Ticket

The message is formatted as follows:
MobilePhoneAuthenticationHex||<*date and time in UTC+0 as yyyy-MM-dd HH:mm:ss>

  • Ticket is considered valid for half an hour from date and time specified in it.
  • Mobile number should be supplied in international format, without country dial code (+), spaces, or dashes.

Example:
MobilePhoneAuthenticationHex|79000000001|2015-12-10 09:12:25

  • If empty string is provided, current date and time in UTC+0 will be used

To test the ticket generation algorithm, you can use a console app and compare results: DirectCrmTicketGenerator.exe