hash the input value and send to the backend in headers

Hi all,

I am looking for a sceanrio, where json payload from the request has a field name MessageContent and this value should be hashed in apigee. This hashed value should be sent to the backend in header.

This scenario is just to identify whether the message is tampered in the middle i.e from apigee to backend.

Here we will be comparing the data that is received in apigee with the data that is recieved at the target server.

please help me in how to achieve this.

Thanks in advance.

0 2 1,059
2 REPLIES 2

There are a number of ways to hash messages. If you are content with a SHA-256 hash, then, there's a really simple way to do what you want. It uses some of the capability that was recently added to the message template in Apigee Edge.

Review:

a Message Template is a string that is used in various places in Apigee Edge policies. As one example, if you use AssignMessage to set a specific payload, then the contents of the Payload element in that policy is treated as a message template. At runtime, Apigee Edge replaces all references to variables, with the values of those variables. Supposing the context variable "bar" holds the value "abc123", in that case a string like

" foo {bar}"

..when evaluated as a Message Template, results in "foo abc123".

OK, now recently several cool enhancements have appeared relating to Message Templates.

  1. there's an expanded set of "functions" you can refer to within Message Templates
  2. You can use AssignMessage/AssignVariable to assign a variable via a message template.

One of the functions that has been added is sha256Hex(var). This produces the hex-encoding of the sha256 hash for the named context variable. Suppose the variable "bar" holds the value "abc". Then this message template:

{sha256Hex(bar)}

...evaluates to the value "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"

Therefore, in order to compute the hash, and inject it as a header, you could use a single assignmessage policy like this:

<AssignMessage name='AM-1'>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>

  <!-- specify the jsonpath as a string -->
  <AssignVariable>
    <Name>json_path_1</Name>
    <Value>$.MessageContent</Value>
  </AssignVariable>

  <!-- Step 2: extract the specific string value via JSONpath -->
  <AssignVariable>
    <Name>extracted_content</Name>
    <Template>{jsonPath(json_path_1,request.content)}</Template>
  </AssignVariable>


 <!-- Step 3: inject a header containing the hash -->
 <Set>
    <Headers>
      <Header name='content-hash'>{sha256Hex(extracted_content)}</Header>
    </Headers>
  </set>
</AssignMessage>

What remains is to configure the backend system to compute the same hash and compare.

This all works.

But..... you may want to rethink your protocol. if an attacker was able to modify the JSON payload while the message is in transit, the attacker will also be able to modify the hash header to match. Passing the unsecured hash code ... doesn't increase security. It makes the hacker's job slightly more difficult, but ... it adds no appreciable security.

The only way to avoid such a pitfall is to use a keyed message authentication code, aka an HMAC. Or sign the content (the hash or the header or etc) in some other way.

And to compute that you would need a Java callout or a JWT policy, or similar.

Thanks Dino-at-Google for your best solution.

can you guide me with the approach of HMAC.