Deprecating September 2026: HTTP Signature Messaging

Construct Messages Using HTTP Signature Security {#restgs-http-message-conf-intro}
==================================================================================

![](/content/dam/documentation/cybs/en-us/topics/platform/rest/getting-started/images/flow-keys-http-3-750x175.svg/jcr:content/renditions/original)  
HTTP signatures use a digital signature to enable the receiver to validate the sender's authenticity and ensure that the message was not tampered with during transit. For more information about HTTP signatures, see the [IETF Draft](https://httpwg.org/ "") that is maintained by the IETF HTTP Working Group.  
Follow these steps to create messages using HTTP signatures:  
![Step 3A: Set the known header values. Step 3B: Calculate the digest HTTP header hash value.
Step 3C: Calculate the signature hash value. Step 3D: Construct the signature HTTP
header value using all of the signature parameter values and signature hash. Step
3E: Combine the HTTP headers and HTTP message body.](/content/dam/documentation/cybs/en-us/topics/platform/rest/getting-started/images/rest-gsg-http-mess-sec-800x525.svg/jcr:content/renditions/original)

HTTP Message Elements {#restgs-http-const-elements}
===================================================

An HTTP message is constructed using HTTP headers and an HTTP message body.

**HTTP Message Headers**
:
Your message header must include these HTTP header fields:

    |  HTTP Header Field  |                                                                                  Description                                                                                   |
    |---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | **content-type**    | Also known as the Multipurpose Internet Mail Extension (MIME) type, it is the identifier of the media or file type resource. You can set the value to: `application/json`      |
    | **host**            | The transaction endpoint (`api.merchant-services.bankofamerica.com`).                                                                                                          |
    | **v-c-date**        | The date of the transaction in the RFC1123 format. Example: `Thu, 18 Jul 2019 00:18:03 GMT`                                                                                    |
    | **v-c-merchant-id** | Your `Bank of America` transacting merchant ID (MID). If you are a portfolio or merchant account user, set this to the transacting merchant ID you send requests on behalf of. |
    | **digest**          | A hash of the HTTP message body that contains your API request. The digest field does not apply to `GET` API requests.                                                         |
    | **signature**       | The digital signature, which is constructed using the values of the other headers and secured by your private key.                                                             |
    [HTTP Header Fields]

**HTTP Message Body**
:
Your API request.

Step 3A: Set Known HTTP Header Values {#restgs-message-set-known}
=================================================================

Set these HTTP header values, which do not require calculation:

content-type
:
Set to the media or file type resource.

host
:
Set to the transaction endpoint.

v-c-date
:
Set to the transaction date in RFC1123 format.

v-c-merchant-id
:
Set to a transacting merchant ID.

Step 3B: Digest Hash Calculation {#restgs-http-message-conf-payload-hash}
=========================================================================

The value of the digest HTTP header is a hashed version of the HTTP message body that you must calculate. This hash value validates the integrity of your message by the receiver.  
Follow these steps to calculate the digest hash:

1. Generate the SHA-256 hash of the JSON payload (message body).
2. Encode the hashed string to Base64.
3. Prepend **SHA-256=** to the front of the hash.
4. Add the message body hash to the digest HTTP header field.  
   Creating a Message Hash Using the Command Line `shasum` Tool

```keyword
echo -n "{"clientReferenceInformation":{"code":"TC50171_3"},"paymentInformation":{"card":{"number":
				"4111111111111111","expirationMonth":"12","expirationYear":"2031"}},"orderInformation":{"amountDetails":
				{"totalAmount":"102.21","currency":"USD"},"billTo”:{“firstName":"John","lastName":"Doe","address1":
				"1MarketSt","locality":"sanfrancisco","administrativeArea":"CA","postalCode":"94105","country":"US",
				"email":"test@bankofamerica.com","phoneNumber":"4158880000"}}}" | shasum -a 256
```

```
echo -n "6ae5459bc8a7d6a4b203e8a734d6a616725134088e13261f5bbcefc1424fc956" | base64
```

Creating a Message Hash Using the Command Line `base64` Tool

```
echo -n "6ae5459bc8a7d6a4b203e8a734d6a616725134088e13261f5bbcefc1424fc956" | base64
```

Creating a Message Hash Using C#

```
public static string GenerateDigest() {
				var digest = "";
				var bodyText = "{ your JSON payload }";
				using (var sha256hash = SHA256.Create()) {
				byte[] payloadBytes = sha256hash
				.ComputeHash(Encoding.UTF8.GetBytes(bodyText));
				digest = Convert.ToBase64String(payloadBytes);
				digest = "SHA-256=" + digest;
				}
				return digest;
				}
```

Creating a Message Using Java

```
public static String GenerateDigest() throws NoSuchAlgorithmException {
				String bodyText = "{ your JSON payload }";
				MessageDigest md = MessageDigest.getInstance("SHA-256");
				md.update(bodyText.getBytes(StandardCharsets.UTF_8));
				byte[] digest = md.digest();
				return "SHA-256=" + Base64.getEncoder().encodeToString(digest);
				}
```

Step 3C: Signature Hash Calculation {#restgs-http-message-conf-signature}
=========================================================================

Before you can construct the signature HTTP header value, you must first generate the *signature hash*. To generate the signature hash value, you must use a Base64-encoded HMAC SHA-256 hash of the signature fields and their values.  
This table describes the signature field values that you must use to calculate the signature hash.

|   Signature Field   |                                                                                                                                                                                                                    Description                                                                                                                                                                                                                    |
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **v-c-date**        | From the header, the date and time in the RFC1123 format. For example: `Date: Thu, 18 Jul 2023, 22:18:03.`                                                                                                                                                                                                                                                                                                                                        |
| **Digest**          | The Base64-encoded SHA-256 hash of the message body. For more information, see [Step 3B: Digest Hash Calculation](/docs/bofa/en-us/platform/developer/all/rest/rest-getting-started/restgs-http-message-intro/restgs-http-message-conf-intro/restgs-http-message-conf-payload-hash.md ""). Example: `Digest: SHA-256=gXWufV4Zc7VkN9Wkv9jh/JuAVclqDusx3vkyo3uJFWU=` Do not include the digest with GET requests. |
| **Host**            | From the header, the endpoint host. For example: `apitest.merchant-services.bankofamerica.com`.                                                                                                                                                                                                                                                                                                                                                   |
| **v-c-merchant-id** | From the header, the merchant ID associated with the request. For example: `v-c-merchant-id: mymerchantid`.                                                                                                                                                                                                                                                                                                                                       |
| **request-target**  | The HTTP method and endpoint resource path. For example: `request-target: post /pts/v2/payments`. > IMPORTANT > Verify that your request-target values match exactly the resource path. For example, ` /pts/v2/payments ` is not the same as ` /pts/v2/payments`**/**` `.                                                                                                                                                                         |
[Signature Fields]

Follow these steps to generate the signature hash value:

1. Generate a byte array of the secret key generated previously. For more information, see [Create a Shared Secret Key Pair](/docs/bofa/en-us/platform/developer/all/rest/rest-getting-started/restgs-http-message-intro/restgs-security-key-pair-intro.md "").
2. Generate the HMAC SHA-256 key object using the byte array of the secret key.
3. Concatenate a string of the required information listed above.  
   For more information, see Creating the Validation String below.
4. Generate a byte array of the validation string.
5. Use the HMAC SHA-256 key object to create the HMAC SHA-256 hash of the validation string byte array.
6. Base64-encode the HMAC SHA-256 hash.

**Signature Hash**

```
signature=”OuKeDxj+Mg2Bh9cBnZ/25IXJs5n+qj93FvPKYpnqtTE=”
```

Creating the Validation String {#restgs-http-message-conf-signature_create-validation-string}
---------------------------------------------------------------------------------------------

To create the validation string, concatenate the required information in the same order as listed in the signature header field parameter. Each item must be on a separate line, and each line should be terminated with a new line character `\n`.  
**Validation String Example**

```keyword
host: apitest.merchant-services.bankofamerica.com\n
date: Thu, 18 Jul 2019 00:18:03 GMT\n
request-target: post /pts/v2/payments/\n
digest: SHA-256=gXWufV4Zc7VkN9Wkv9jh/JuAVclqDusx3vkyo3uJFWU=\n
v-c-merchant-id: mymerchantid
```

**Generating a Signature Hash in C#**

```
private static string GenerateSignatureFromParams(string signatureParams, string secretKey) {
var sigBytes = Encoding.UTF8.GetBytes(signatureParams);
var decodedSecret = Convert.FromBase64String(secretKey);
var hmacSha256 = new HMACSHA256(decodedSecret);
var messageHash = hmacSha256.ComputeHash(sigBytes);
return Convert.ToBase64String(messageHash);
}
```

**Generating a Signature Hash in Java**

```
public static String GenerateSignatureFromParams(String keyString, 
String signatureParams) throws InvalidKeyException, NoSuchAlgorithmException {
byte[] decodedKey = Base64.getDecoder().decode(keyString);
SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "HmacSHA256");
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
hmacSha256.init(originalKey);
hmacSha256.update(signatureParams.getBytes());
byte[] HmachSha256DigestBytes = hmacSha256.doFinal();
return Base64.getEncoder().encodeToString(HmachSha256DigestBytes);}
```

Step 3D: Constructing the Signature Header {#restgs-http-message-headers}
=========================================================================

After you generate a signature hash, you can construct the signature HTTP header value.  
The signature HTTP header value is constructed using these parameters:

| Signature Parameter |                                                                                                                                                                                        Description                                                                                                                                                                                        |
|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **keyid**           | The serial number of the signing certificate/key pair. Obtain this in the `BA360` Key Management area. For more information, see [Step 2A: Creating a Shared Secret Key Pair](/docs/bofa/en-us/platform/developer/all/rest/rest-getting-started/restgs-http-message-intro/restgs-security-key-pair-intro/restgs-security-key-pair-task.md "").          |
| **algorithm**       | The HMAC SHA256 algorithm used to encrypt the signature. It should be formatted: `HmacSHA256`.                                                                                                                                                                                                                                                                                            |
| **headers**         | The signed-header values calculated in the signature: * `digest` * `host` * `request-target` * `v-c-date` * `v-c-merchant-id` > IMPORTANT > If you are using a meta-key, set the v-c-merchant-id signature-parameter value to the meta-key creator's ID. Then set the v-c-merchant-id HTTP header value to the transacting merchant ID (MID) that you are sending a request on-behalf of. |
| **signature**       | The signature hash.                                                                                                                                                                                                                                                                                                                                                                       |
[Signature Parameters]

![](/content/dam/documentation/cybs/en-us/topics/platform/rest/getting-started/images/rest-gsg-http-mess-sec-port-800x245.svg/jcr:content/renditions/original)

**Signature Field Format**
:
`Signature:"keyid:"[keyid]",algorithm="[encryption algoritm]",headers="field1" "field2" "field3" "etc.", signature="[signature hash]"`

**Signature Example**
:

    ```
    Signature:"keyid="123abcki-key1-key2-key3-keyid1234567", 
    algorithm="HmacSHA256", headers="host date request-target digest v-c-merchant-id", 
    signature="hrptKYTtn/VfwAdUqkrQ0HT7jqAbagAbFC6nRGXrNzE="
    ```

Step 3E: Complete Message with HTTP Signature {#restgs-http-message-complete}
=============================================================================

Combine all of the HTTP header values with your HTTP message body to construct your HTTP signature message.  
To test your message, you can send a test request to `Bank of America`. For more information, see [Test Your Setup](/docs/bofa/en-us/platform/developer/all/rest/rest-getting-started/restgs-http-message-intro/restgs-test.md "").
