【问题标题】:AES Encryption between C# and F5 load balancer / TCLC# 和 F5 负载均衡器/TCL 之间的 AES 加密
【发布时间】:2014-02-11 12:14:41
【问题描述】:

我想使用加密将流量发送到我的 F5 BIG IP 负载均衡器,并让它使用自己的本机 CRYPTO:: 方法来解密 base64 编码的字符串。 我能够在设备和 Visual Studio 2012 控制台应用程序中加密和解密字符串,但无法在相反的环境中解密加密字符串。

这里关于如何以 CRYPTO 或 C# 理解的兼容格式获取以下密钥的任何建议都会大有帮助!

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

似乎在 CRYPTO:: 中它需要十六进制格式,我尝试将其转换为如下所示,但这对我没有帮助。

C# 控制台应用代码:

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);

        }
    }
}

这是控制台输出:

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

这是 F5 / TCL 代码:

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

}

F5/TCL 输出日志文件:

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

【问题讨论】:

    标签: hex byte tcl aes f5


    【解决方案1】:

    您的代码中发生了一些关于密钥和 IV 的非常奇怪的事情。

    首先,您指定的键是 16 个字符。在 UTF-8 中,这些结果为 16 个字节。但是,您在 C# 代码中指定了 32 字节(256 位)的密钥。另请注意,许多库(错误地)使用 AES-256 来表示具有 256 位块大小的 Rijndael。最好只使用 AES-128 并专注于使您的协议和代码安全。

    其次,一个键永远不能是一个字符串。对于可以使用的值,字符串通常受到限制。例如。无法输入控制代码。这意味着您的密钥永远不会达到其预期强度。如果您想使用静态键,您应该像在 F5 代码中那样以十六进制指定它。

    静态 IV 没有多大意义。 IV 的整个想法是确保如果您使用已处理的值加密块,您将生成不同的密文。所以请使用随机IV,并将其放在密文前面。

    您似乎对在明文 (UTF-8) 和密文 (Base 64) 上使用编码/解码很感兴趣。所以请尝试按照上面给出的建议再试一次。

    【讨论】:

    • 请注意,我完全不熟悉那个 F5 代码。它是一种特定的脚本语言吗?哦,是TCL,我去看看……该死,需要注册……
    • 做到了!我正在将密钥大小设置为 32 字节,因为我遇到了问题,所以密文加密匹配,终于!感谢您对向量的建议,我知道它可以随机化它(实际上我认为在 TCL 上默认情况下会这样做)......当你说放在前面时,你是怎么做的
    • 对于 AES,IV 总是 16 字节(一个块大小)。因此,您可以在加密期间将其放在密文前面(使用密码安全的随机数生成器来创建它)并在解密之前将其剥离并放入 IV 变量中。 IV | ciphertext 用数学符号表示。
    • 如果这解决了您的问题,请点击答案旁边的接受按钮(左侧的 V 标记)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多