Digital Signatures

How the Digital Signature Works

Calculating the Signature

Green Dot issues each partner a secret key used to calculate the digital signature. Calculating each key involves the following steps:

  1. Sorting the headers (except the Signature header) and removing extra spaces around the fields.
  2. Concatenating the headers using a delimiter &.
  3. ASCII encoding the SecretKey.
  4. UTF8 encoding the concatenated header string.
  5. Hashing the string using SHA-256 (use the key as SecretKey). Secret Key is shared between Green Dot and the partner.

Coding Used

Green Dot uses the following C# code to generate the signature.

var dict = requestHeaderDictionary.OrderBy(t => t.Key).ToList();
var pairs = dict.Where(p => (p.Key != “x-gdn-signature”) && (!string.IsNullOrWhiteSpace(p.Value))).Select(x => string.Format("{0}{1}{2}", x.Key, ":", x.Value));var 
concatnatedString = string.Join("&", pairs).ToLower();
var encoding = new ASCIIEncoding();
byte\[] secretKeyBytes = encoding.GetBytes(secret);
byte\[] signature = Encoding.UTF8.GetBytes(concatnatedString);using (var hmac = new HMACSHA256(secretKeyBytes))
  byte\[] signatureBytes = hmac.ComputeHash(signature);        
  return string.Concat(signatureBytes.Select(b => b.ToString("X2")).ToArray());

NOTE: Before performing the concatenation/hashing, make sure all characters are converted to lower case and the strings are trimmed (left/right) for the extra white spaces. Do not include headers that have null/empty values.

Sample Procedures

Following are the steps to generate the digital signature. You may check the results of each step.

  1. //sortvar dict = requestHeaderDictionary.OrderBy(t => t.Key).ToList();
  2. //concatenatevar pairs = dict.Where(p => (p.Key != WebApiRequestHeaders.X_GDN_Signature) && (!string.IsNullOrWhiteSpace(p.Value))).Select(x => string.Format("{0}{1}{2}", x.Key, ":", x.Value));var concatenatedString = string.Join("&", pairs).ToLower();
    The is x-gdn-channeltype:1&x-gdn-devicetype:2&x-gdn-encryptiontype:1&x- gdn-ipaddress: 948af2fad3c5&x-gdn-programnumber:bahu-bc2019&x-gdn-timestamp:2020-05- 22t03:07:53z
  3. var encoding = new ASCIIEncoding();byte[] secretKeyBytes = encoding.GetBytes(secret);
    The secret is i4pu7k3y secretKeyBytes.Length is 8
  4. byte[] signature = Encoding.UTF8.GetBytes(concatenatedString); signature.Length is 211
  5. using (var hmac = new HMACSHA256(secretKeyBytes))
    byte[] signatureBytes = hmac.ComputeHash(signature);
    return string.Concat(signatureBytes.Select(b =>b.ToString("X2")).ToArray());
    signatureBytes.Length is 32
    The x-gdn-signature is

Invalid X_GDN  Signature Error

<base_response xmlns:i="" xmlns="">
<gd_response_message>Invalid X_GDN_Signature</gd_response_message>
<gd_transaction_reference>3b938107-cef0-4515-8e0f- efca6e45d656</gd_transaction_reference>
<partner_transaction_reference i:nil="true" />

Sample Input and Resulting Signature

Sample Header Input

      "x-gdn-timestamp": "2020-05-22T03:07:53Z",
      "x-gdn-encryptiontype": "1",
      "x-gdn-messageid": "61aa6e58-b442-4839-8432-948af2fad3c5",    
      "x-gdn-channeltype": "1",    
      "x-gdn-devicetype": "2",   
     "x-gdn-ipaddress": "",    
      "x-gdn-programnumber": "Bahu-BC2019"

Sample Body Input

"gd_retailer_key”: "2433",
"amount”: "22.22"

Sample Concatendated Values


Resulting Signature

Using the sample secret key i4pu7k3y, the resulting hash/signature would be as follows: