Question

I would like to use encryption to send traffic to my F5 BIG IP load balancer and have it use its own native CRYPTO:: methods to decrypt a base64 encoded string. I am able to encrypt and decrypt a string within the appliance and within a Visual Studio 2012 console application but I cannot decrypt an encrypted string in the opposing environment.

Any suggestion here as to how to get the following keys in a compatible format that CRYPTO or C# understands would go a long way!

// C# key and vector declaration:
private const string AesIV = @"!QAZ2WSX#EDC4RFV";
private const string AesKey = @"5TGB&YHN7UJM(IK<";

It appears that in CRYPTO:: it needs it in hex format, I tried to convert it as seen below but that didnt help me.

C# console app code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;
using System.Threading;

namespace ssoconsole_encrypt
{
    class Program
    {
        private const string AesIV = @"!QAZ2WSX#EDC4RFV";
        private const string AesKey = @"5TGB&YHN7UJM(IK<";
    //        set key "abed1ddc04fbb05856bca4a0ca60f21e" 
    //set iv "d78d86d9084eb9239694c9a733904037" 

    //  set key "56bca4a0ca60f21e" 
//  set iv "39694c9a73390403" 

        /// <summary>
        /// AES Encryption
        /// </summary>
        /// 


        static public string Encrypt(string text)
        {
            // AesCryptoServiceProvider
            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();

            aes.BlockSize = 128;
            aes.KeySize = 256;         
            aes.IV = Encoding.UTF8.GetBytes(AesIV);
            aes.Key = Encoding.UTF8.GetBytes(AesKey);

            string keyme = BitConverter.ToString(aes.Key);
            string ivme  = BitConverter.ToString(aes.IV);
            Console.WriteLine(string.Format("The converted key is: {0}",keyme));
            Console.WriteLine(string.Format("The converted iv is: {0}", ivme));
           Console.WriteLine(System.Text.Encoding.UTF8.GetString(aes.Key));
          // Thread.Sleep(10000);

            //Console.WriteLine(aes.Key.ToString());
            aes.Mode = CipherMode.CBC;
           aes.Padding = PaddingMode.PKCS7;
          //  aes.Padding = PaddingMode.Zeros;

                // Convert string to byte array
                //byte[] src = Encoding.Unicode.GetBytes(text);
            byte[] src = Encoding.UTF8.GetBytes(text);

                // encryption
                using (ICryptoTransform encrypt = aes.CreateEncryptor())
                {
                    byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);

                    // Convert byte array to Base64 strings
                    return Convert.ToBase64String(dest);
                }


        }

        /// <summary>
        /// AES decryption
        /// </summary>
        static public string Decrypt(string text)
        {

            // AesCryptoServiceProvider
            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
            aes.BlockSize = 128;
            aes.KeySize = 256;

            aes.IV = Encoding.UTF8.GetBytes(AesIV);
            aes.Key = Encoding.UTF8.GetBytes(AesKey);

            //aes.IV = Encoding.UTF8.GetBytes(@"01020304050607080900010203040506");
            //aes.Key = Encoding.UTF8.GetBytes(@"01020304050607080900010203040506");
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            // Convert Base64 strings to byte array
            byte[] src = System.Convert.FromBase64String(text);

            try
            {
                // decryption
                using (ICryptoTransform decrypt = aes.CreateDecryptor())
                {
                    byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
                   // return Encoding.Unicode.GetString(dest);
                    return Encoding.UTF8.GetString(dest);
                }

            }

            catch (CryptographicException e)
            {
                return e.ToString();

            }
        }

        static void Main()

        {

            string username = "jschoombee";
            string encrypted = Encrypt(username);
        string decrypted = Decrypt(encrypted);
       //     string decrypted = Decrypt("epvhTN55JnnVV9DBn1Cbsg==");
         //   string decrypted = Decrypt(encrypted);

           Console.WriteLine(string.Format("jschoombee encrypted is : {0}",encrypted));

            Console.WriteLine(string.Format("the Decrypted username for jp is : {0}", decrypted));


            Thread.Sleep(1000000);

        }
    }
}

This is the Console Output:

The converted key is: 35-54-47-42-26-59-48-4E-37-55-4A-4D-28-49-4B-3C
The converted iv is: 21-51-41-5A-32-57-53-58-23-45-44-43-34-52-46-56
5TGB&YHN7UJM(IK<
jschoombee encrypted is : tGG9Un6VqcAOTQawlxwRXg==
the Decrypted username for jp is : jschoombee

This it the F5 / TCL code:

when RULE_INIT {
set static::hexkey "355447422659484E37554A4D28494B3C"
log local0.info"====Rule_Init===="
log local0.info "Key is $static::hexkey"
log local0.info"================="
}

when HTTP_REQUEST_DATA {
set iv "2151415A325753582345444334524656"
set text_to_encrypt "jschoombee"
set enc_out_no_binary [CRYPTO::encrypt -alg aes-256-cbc -keyhex $static::hexkey -ivhex $iv $text_to_encrypt]
set dec_in [CRYPTO::decrypt -alg aes-256-cbc -keyhex $static::hexkey -ivhex $iv $enc_out_no_binary]

log local0.info "The decrypted NO binary $dec_in"
log local0.info "The Encrypted NO binary Base64 is: [b64encode "$enc_out_no_binary"]"
binary scan $enc_out_no_binary H* enc_hex
log local0.info "The Encrypted NO binary Hex is: $enc_hex"
log local0.info "This is the IV $iv"
HTTP::release

}

The F5/TCL Output Log File:

Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: The decrypted NO binary jschoombee
Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: The Encrypted NO binary Base64 is: Rlz4cC9SlpRyON4cZI+dtQ==
Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: The Encrypted NO binary Hex is: 465cf8702f5296947238de1c648f9db5
Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: This is the IV 2151415A325753582345444334524656
Was it helpful?

Solution

There are some very strange things happening in your code regarding the key and IV.

First of all the key you've specified is 16 characters. In UTF-8 those result in 16 bytes. You are however specifying a key of 32 bytes (256 bits) in your C# code. Also be warned that many libraries (incorrectly) use AES-256 to mean Rijndael with a 256 bit block size. It's probably better to just use AES-128 and focus on making your protocol and code secure.

Second, a key can never be a character string. A character string normally is restricted with regards to which values can be used. E.g. control codes cannot be entered. This means that your key will never reach its intended strength. If you want to use a static key, you should specify it in hexadecimals as you do in your F5 code.

A static IV does not make much sense. The whole idea of the IV is to make sure that you will generate a different ciphertext if you encrypt a block with a value already processed. So please use a random IV, and place it in front of your ciphertext.

You seem to have the hang on using encoding/decoding on your plaintext (UTF-8) and ciphertext (Base 64). So please try and follow the advice given above and try again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top