Place holder
Place holder
Green Dot issues each partner a secret key used to calculate the digital signature. Calculating each key involves the following steps:
Sorting the headers (except the Signature header) and removing extra spaces around the fields.
Concatenating the headers using a delimiter &.
ASCII encoding the SecretKey.
UTF8 encoding the concatenated header string.
Hashing the string using SHA-256 (use the key as SecretKey). Secret Key is shared between Green Dot and the partner.
Following is the C# code Green Dot uses to generate the signature.
//sort
var dict = requestHeaderDictionary.OrderBy(t => t.Key).ToList();
//concatenate
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.
Following are the steps to generate the digital signature. You may check the results of each step.
//sort
var dict = requestHeaderDictionary.OrderBy(t => t.Key).ToList();
//concatenate
var 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:192.168.1.1&x-gdn-messageid:61aa6e58-b442-4839-8432- 948af2fad3c5&x-gdn-programnumber:bahu-bc2019&x-gdn-timestamp:2020-05- 22t03:07:53z
var encoding = new ASCIIEncoding();
byte[] secretKeyBytes = encoding.GetBytes(secret);
The secret is i4pu7k3y secretKeyBytes.Length is 8
byte[] signature = Encoding.UTF8.GetBytes(concatenatedString);
signature.Length is 211
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
0116eb70450b743f26ccc701f598341f3e6d5b04d50979897571125928d65e8d
<base_response xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://greendotcorp.com/WebServices/Corporate/GDFNReloadServices/">
<gd_response_code>351000019</gd_response_code>
<gd_response_date>2020-05-27T07:32:57.0244211Z</gd_response_date>
<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" />
</base_response>
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": "192.168.1.1",
"x-gdn-programnumber": "Bahu-BC2019"
}
Sample Body Input
{
"gd_retailer_key”: "2433",
"amount”: "22.22"
}
Sample Concatendated Values
“x-gdn-channeltype:1&x-gdn-devicetype:2&x-gdn-encryptiontype:1&x-gdn-ipaddress:192.168.1.1&x-gdn-messageid:61aa6e58-b442-4839-8432-948af2fad3c5&x-gdn-programnumber:bahu-bc2019&x-gdn-timestamp:2020-05-22t03:07:53z”
Resulting Signature
Using the sample secret key i4pu7k3y, the resulting hash/signature would be as follows:
0116eb70450b743f26ccc701f598341f3e6d5b04d50979897571125928d65e8d
byte[] signatureBytes = hmac.ComputeHash(signature);
return string.Concat(signatureBytes.Select(b => b.ToString("X2")).ToArray());