C#和F5负载均衡器/TCL之间的AES加密



我想使用加密将流量发送到我的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

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

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

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

静态IV没有多大意义。IV的全部思想是确保如果用已经处理的值加密块,则会生成不同的密文。因此,请使用随机IV,并将其放在您的密文前面。

您似乎已经掌握了对明文(UTF-8)和密文(Base64)进行编码/解码的技巧。因此,请尝试并遵循上面给出的建议,然后再试一次。

最新更新