How to use a RSA public key to encrypt headers on a Citrix ADC.

Encryption headers?

If you ever find yourself in the need to make it hard to read headers and base64 encoding isn’t enough, because lets be clear, base64 encoding isn’t encryption and everyone can decode it, then you might find yourself in the need of encrypting the header value with a RSA public key, that you can later decode on the backend server using the private key.

How to generate a public/private key-pair.

First, we need to generate our public and private key pair, to do I will load up my trusted openssl to create the private key

openssl genrsa -aes256 -out private.pem 1024

You will be prompted to enter a pass phrase, this will needed to load the key

Next, we need to create a public key, that can use to encrypt the headers on the ADC on, I will do using openssl again and outputting the public key directly in my terminal

openssl rsa -in private.pem -RSAPublicKey_out

To read the key (private.pem) we will need to enter the pass phrase we created before

So now we have our private key and the public key which is:

—–BEGIN RSA PUBLIC KEY—–MIGJAoGBAMGf546XMUpqjoCx6GcZBZKTMdf2OUGlpAyD2RJ9fTMxjo79WvkA69T9I9d5JERG21dzDcBSPp2kmnEmwXPss+/3EnQIDAX4gtSS0zj/3WNd3h2ljrHkfqbWLJtVzz93JqfNVB3b8uMRK34usgIp78Da25yYrij/0ZtJAP12vJQ/AgMBAAE=
—–END RSA PUBLIC KEY—–

Adding the public key to the ADC

Next we need to create our expression on the ADC, so we can call it later on.

add policy expression RSA_Pub “\”—–BEGIN RSA PUBLIC KEY—–MIGJAoGBAMGf546XMUpqjoCx6GcZBZKTMdf2OUGlpAyD2RJ9fTMxjo79WvkA69T9I9d5JERG21dzDcBSPp2kmnEmwXPss+/3EnQIDAX4gtSS0zj/3WNd3h2ljrHkfqbWLJtVzz93JqfNVB3b8uMRK34usgIp78Da25yYrij/0ZtJAP12vJQ/AgMBAAE=—–END RSA PUBLIC KEY—–\””

It will look like this when you add it on the ADC (notice that my nsroot asks for a passphrase for a key, but that is another blog post)

Now that we our public RSA part is available on the ADC as an expression, we can start to use it.
To showcase it i will create a simple header insert called RSAENCRYPTED that will include the TXID “TXID
Returns the HTTP Transaction ID. The value is a function of an internal transaction number, system boot time and system mac address. HTTP.REQ.TXID is same as HTTP.RES.TXID
.”

First I will create a rewrite policy and action that will insert the header on the RESPONSE (This is cheating a little, but it’s easier to show using inspect in a browser)

My action:

add rewrite action rw_act_encrypt_header insert_http_header RSAENCRYPTED http.RES.TXID

My policy:

add rewrite policy rw_pol_encrypt_header true rw_act_encrypt_header

And then I will bind it to a server I have running, which is just a default apache on an ubuntu

bind lb vserver name -policyName rw_pol_encrypt_header -priority 100 -gotoPriorityExpression END -type RESPONSE

Now when I make a request to against the server, the response will insert the header RSAENCRYPTED with the value of the transaction ID
(You can click on the picture to get a bigger view)

Now the whole idea was that our headed should be encrypted, so lets add expression to our rewrite

It’s done by adding the following bid of expression: PKEY_ENCRYPT_PEM(RSA_PUB)

The RSA_PUB is the name of our expression, the action would look like this, if we wanted to enable the encryption, when we added it the first time (Else you have to update the expression)

add rewrite action rw_act_encrypt_header insert_http_header RSAENCRYPTED “http.RES.TXID.PKEY_ENCRYPT_PEM(RSA_Pub)”

Lets take a look in the inspect again
(You can click on the picture to get a bigger view)

It’s unreadable now.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.