Overview
The PaymentKeys Application Framework takes advantage a cryptographic hash technology called
HMACSHA1 that provides both sender and message authentication. This hash method requires the use of a secret key for generating a one-way hash of the message being encrypted.
To provide authentication of a sender and the message being sent, the sender and receiver of the message use a shared secret key. The sender uses the secret key to generate the HMACSHA1 hash signature of the message to be sent. Then, the sender sends both the unencrypted message and the hashed signature of the message to the receiver.
The receiver uses the shared secret key to generate their own HMACSHA1 hash signature of the message. If the receiver's hash signature matches the sender's hash signature, then the receiver can be certain the message was sent by the receiver and that the message has not been tampered with in transit.
When the message is sent using SSL, SSL handles the responsibility of encrypting the overall HTTP string and any sensitive data it may contain.
The Shared Secret Key
Upon successful registration with PaymentKeys, your company was assigned and delivered a unique GatewayCode. This GatewayCode is the secret key that must be used when generating the HMACSHA1 hash signature for each API request sent to the PaymentKeys Application Framework gateway.
Generating the Hash Signature
As mentioned in the wiki document,
Making a REST API Call, your software application will generated a JSON string that contains the API command to be executed and its associated parameters. This JSON string is the 'message' that you will hash using HMACSHA1 to generate the signature.
When you contruct your HTTP POST or GET request, the
api_sig field needs to contain the base64 encoded hash signature you just generated and the
api_call field will contain the unencrypted JSON string that defines the API command to execute.
Preventing Duplicate Message Authentication
The one problem with using a hash signature to authenticate a sender and their message is the fact that a message and its hash signature could be resent later by an unauthorized party and, without some additional security measures in place, the message would still authenticate.
To prevent this scenario from occurring, you will notice in the Framework Command APIs sections that every command sent as a JSON string includes a required field named
api_call_id. The
api_call_id field must contain a value that is unique and different for each api call. This field value allows the PaymentKeys servers to ensure that each specific API command is only sent once and can never be sent again.
Suggestions for the value of
api_call_id include a GUID, a unique transaction ID generated internally by your software for each API call or even a string representation of the current date/time of your server down to the millisecond.
HMACSHA1 Code Samples and References¶
JAVA by SUN
Visual Basic .NET Framework 3.5 Example |
’Define a command object for populating command parameters Dim PK_Command As New PK_PaymentKeyAdmin_Command
’Build the command to send to the PaymentKeys Application Framework
PK_Command.command = "paymentkey.activate"
PK_Command.version = "1.0" PK_Command.api_call_id = Guid.NewGuid.ToString
PK_Command.paymentkey = "v1111_00000_00000_00000.pk"
’Serialize the command object to a JSON string Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer() Dim api_call As String = serializer.Serialize(PK_Command)
’Create HMACSHA1 signature hash for the JSON command string using the GatewayCode Dim sha1 As New System.Security.Cryptography.HMACSHA1()
’Specify the GatewayCode secret key
sha1.Key = System.Text.Encoding.UTF8.GetBytes("PK_Demo")
’Convert the JSON command string to a byte array Dim byteArray As Byte() = System.Text.Encoding.UTF8.GetBytes(api_call)
’Generate the hash signature Dim api_sig As String = Convert.ToBase64String(sha1.ComputeHash(byteArray))
|
C# .NET Framework 3.5 Example |
//Define a command object for populating command parameters
PK_PaymentKeyAdmin_Command PK_Command = new PK_PaymentKeyAdmin_Command();
//Build the command to send to the PaymentKeys Application Framework
PK_Command.command = "paymentkey.activate";
PK_Command.version = "1.0";
PK_Command.api_call_id = Guid.NewGuid.ToString;
PK_Command.paymentkey = "v1111_00000_00000_00000.pk";
//Serialize the command object to a JSON string
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); string api_call = serializer.Serialize(PK_Command);
//Create HMACSHA1 signature hash for the JSON command string using the GatewayCode
System.Security.Cryptography.HMACSHA1 sha1 = new System.Security.Cryptography.HMACSHA1();
//Specify the GatewayCode secret key
sha1.Key = System.Text.Encoding.UTF8.GetBytes("PK_Demo");
//Convert the JSON command string to a byte array byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(api_call);
//Generate the hash signature string api_sig = Convert.ToBase64String(sha1.ComputeHash(byteArray));
|