Skip to main content

Generating a Signature

The most difficult part of building a proper request to the API is building the signature and signing it with a shared secret. In any language, a properly signed signature for the request should be generated using the following steps:

  1. Combine key components of the request into a single string, using a format where each value is followed by a carriage return and line feed character. The format and table with recommended replacements is below:

        {Method}\r\n{Host}\r\n{URL}\r\n{Unix Timestamp}\r\n{API Key}\r\n{Access Key}\r\n
    KeywordRecommended Replacement
    MethodHTTP Method in ALL CAPS (e.g. GET, PUT, POST, DELETE, HEAD, OPTIONS).
    HostHost name of server in lower case (e.g. api.ravenslingshot.com).
    URLAbsolute URI minus query string in lower case (e.g. /fieldcomputers/460/PrescriptionMaps).
    Unix TimestampUnix style timestamp of the request (number of seconds since midnight on Jan 1 1970).
    API KeySlingshot API Key in the case in which it was generated.
    Access KeySlingshot Access Key in the case in which it was generated.
  2. Generate an HMAC (Hash-based Message Authentication Code) using the SHA1 algorithm from the string constructed above and a 'shared secret' key.

  3. The generated HMAC should then be passed along to the Slingshot API Server as the value of the X-SS-Signature request header. When the Slingshot API Server receives the request, it will do the same using the Shared Secret that matches the API Key specified in the request. If the two HMAC signatures match, the request will be considered authentic.

Examples

A function for building the signature is shown in various languages below. Test the implementation by making sure the function produces an output of EssUFos9uCpS1FFUFaPTE3Qucz0= when provided the following strings (all encoded as UTF8):

KeywordReplacement
MethodGET
Hosthost.company.com
URL/absolute/path
Unix Timestamp1234567890
API Key071X7Hc9zdfElbB2fUqQVjAQ3BsOPa4F9l3yqekl
Access Key00000000-0000-0000-0000-000000000000
Shared SecretRecQ1RrXLNP/WnMqrJsj5WsuXNDmCOoCg3AV85DQ

C#

private static string CalculateSignature(string sharedSecret,
string method,
string url,
string host,
string apiKey,
string accessKey,
string timestamp)
{
string signatureBlockTemplate = "{0}\r\n{1}\r\n{2}\r\n{3}\r\n{4}\r\n{5}\r\n";
string blockToSign = String.Format(signatureBlockTemplate,
method.ToUpperInvariant(),
host.ToLowerInvariant(),
url.ToLowerInvariant(),
timestamp,
apiKey,
accessKey);

using (HMACSHA1 hmacsha1 = new HMACSHA1())
{
Encoding encoder = new UTF8Encoding();
hmacsha1.Key = Convert.FromBase64String(sharedSecret);
byte[] hmacsig = hmacsha1.ComputeHash(encoder.GetBytes(blockToSign));
return Convert.ToBase64String(hmacsig);
}
}

Java

private String CalculateSignature(String sharedSecret,
String method,
String url, String host,
String apiKey,
String accessKey,
String timestamp) throws java.security.SignatureException
{
private String signatureBlockTemplate = "%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n";
String blockToSign = String.format(signatureBlockTemplate,
method.toUpperCase(Locale.US),
host.toLowerCase(Locale.US),
url.toLowerCase(Locale.US),
timestamp,
apiKey,
accessKey);
String result;

try
{
// get an hmac_sha1 key from the raw key bytes
SecretKeySpec signingKey =
new SecretKeySpec(com.ss.sscompanion.utilities.Base64.decode(sharedSecret),
HMAC_SHA1_ALGORITHM);

// get an hmac_sha1 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);

// compute the hmac on input data bytes
byte[] rawHmac = mac.doFinal(blockToSign.getBytes());

// base64-encode the hmac
result = com.ss.sscompanion.utilites.Base64.encodeBytes(rawHmac);
}
catch (Exception e)
{
throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
}
return result;
}

PHP

private function calculateSignature($sharedSecret,
$method,
$url,
$host,
$apiKey,
$accessKey,
$timestamp)
{
$signatureBlock =
sprintf("%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n",
strtoupper($method),
$host,
strtolower($url),
$timestamp,
$apiKey,
$accessKey);

return base64_encode(hash_hmac('sha1', $signatureBlock, base64_decode($sharedSecret, true), true));
}