Forum Discussion
use irule to sign data using sha256
- Dec 01, 2022
Hi Quangtran,
do you want to calculate the HMAC-checksum for the entire POST-data (Scenario 1) or just the "data" value itself (Scenario 2)?
Scenario 1:
hmac-sha256( the received POST string as-is including outer curly braces )
Scenario 2:
hmac-sha256( FdQZxoYBLPCgv2VPzdiUDA2Xj9KIJ\/I4BSzViIp\/CG\/ktrcdtXGYXQzGaa71R )
The quickly code iRule below uses Scenario 1 as input for HMAC calculation. The iRule uses 4 logical steps to read the payload, calculate the checksum, define the new payload and finally insert the new payload to the HTTP request before its getting forwarded to your backend. Every single step could be easily adjusted based on your needs...
when RULE_INIT { # Define global configuration options set static::max_payload_size "1048576" ;# Limiter for maximum HTTP payload size in bytes set static::hmac_key "Hello World!" ;# Secrect for HMAC signing } when HTTP_REQUEST { # Check if HTTP request contains any HTTP payload and if its size does not exceed our limits... if { ( [string tolower [HTTP::path]] equals "/login" ) and ( [HTTP::method] equals "POST" ) and ( [HTTP::header value "Content-Length"] ne "" ) and ( [HTTP::header value "Content-Length"] < $static::max_payload_size ) } then { # Collect the HTTP payload and trigger HTTP_REQUEST_DATA event HTTP::collect [HTTP::header value "Content-Length"] } } when HTTP_REQUEST_DATA { # Define the input used for HMAC signing set temp(hmac_input) [HTTP::payload] # Compute the HMAC checksum for the input using our secret key set temp(hmac_output) [b64encode [CRYPTO::sign -alg hmac-sha256 -key $static::hmac_key $temp(hmac_input)]] # Contruct the new payload set temp(new_payload) "[string trimright [HTTP::payload] "\}"],\"hashsha256\":\"$temp(hmac_output)\"\}" # Replace the payload HTTP::payload replace 0 [HTTP::payload length] $temp(new_payload) unset -nocomplain temp }
At later stage we may or may not combine those 4 logical steps into a single syntax line, to reduce processing overhead to a minimum.. 😉
when HTTP_REQUEST_DATA { # Replace the payload with HMAC signed payload... HTTP::payload replace 0 [HTTP::payload length] "[string trimright [HTTP::payload] "\}"],\"hashsha256\":\"[b64encode [CRYPTO::sign -alg hmac-sha256 -key $static::hmac_key [HTTP::payload]]]\"\}" }
Cheers, Kai
Thank you and really appreciate the feedback.
I will answer your question as follows,
Question 1: all your comments are correct, that's what i want
Question 2: I want to use a standardized HMAC-SHA256 checksum
Question 3: I need the checksum to be added to the original POST data in base64 format, and form
HTTP REQUEST
- header: Unchanged
POST /login HTTP1/1
Host: xxxxxx
<some other fields>
- Body:
<data> + <Hash the data string using SHA256 >
request data
{"data":"FdQZxoYBLPCgv2VPzdiUDA2Xj9KIJ\/I4BSzViIp\/CG\/ktrcdtXGYXQzGaa71R"
request data after using iRule
{"data":"FdQZxoYBLPCgv2VPzdiUDA2Xj9KIJ\/I4BSzViIp\/CG\/ktrcdtXGYXQzGaa71R","hashsha256":"akfjdafjGDJudsjSSlfdjfdsus"}
thanks you, Kai
Hi Quangtran,
do you want to calculate the HMAC-checksum for the entire POST-data (Scenario 1) or just the "data" value itself (Scenario 2)?
Scenario 1:
hmac-sha256( the received POST string as-is including outer curly braces )
Scenario 2:
hmac-sha256( FdQZxoYBLPCgv2VPzdiUDA2Xj9KIJ\/I4BSzViIp\/CG\/ktrcdtXGYXQzGaa71R )
The quickly code iRule below uses Scenario 1 as input for HMAC calculation. The iRule uses 4 logical steps to read the payload, calculate the checksum, define the new payload and finally insert the new payload to the HTTP request before its getting forwarded to your backend. Every single step could be easily adjusted based on your needs...
when RULE_INIT {
# Define global configuration options
set static::max_payload_size "1048576" ;# Limiter for maximum HTTP payload size in bytes
set static::hmac_key "Hello World!" ;# Secrect for HMAC signing
}
when HTTP_REQUEST {
# Check if HTTP request contains any HTTP payload and if its size does not exceed our limits...
if { ( [string tolower [HTTP::path]] equals "/login" )
and ( [HTTP::method] equals "POST" )
and ( [HTTP::header value "Content-Length"] ne "" )
and ( [HTTP::header value "Content-Length"] < $static::max_payload_size ) } then {
# Collect the HTTP payload and trigger HTTP_REQUEST_DATA event
HTTP::collect [HTTP::header value "Content-Length"]
}
}
when HTTP_REQUEST_DATA {
# Define the input used for HMAC signing
set temp(hmac_input) [HTTP::payload]
# Compute the HMAC checksum for the input using our secret key
set temp(hmac_output) [b64encode [CRYPTO::sign -alg hmac-sha256 -key $static::hmac_key $temp(hmac_input)]]
# Contruct the new payload
set temp(new_payload) "[string trimright [HTTP::payload] "\}"],\"hashsha256\":\"$temp(hmac_output)\"\}"
# Replace the payload
HTTP::payload replace 0 [HTTP::payload length] $temp(new_payload)
unset -nocomplain temp
}
At later stage we may or may not combine those 4 logical steps into a single syntax line, to reduce processing overhead to a minimum.. 😉
when HTTP_REQUEST_DATA {
# Replace the payload with HMAC signed payload...
HTTP::payload replace 0 [HTTP::payload length] "[string trimright [HTTP::payload] "\}"],\"hashsha256\":\"[b64encode [CRYPTO::sign -alg hmac-sha256 -key $static::hmac_key [HTTP::payload]]]\"\}"
}
Cheers, Kai
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com