gpt4 book ai didi

c# - 查询字符串参数混淆

转载 作者:太空狗 更新时间:2023-10-29 19:56:26 24 4
gpt4 key购买 nike

我想混淆 ASP.NET 中的一个查询字符串参数。该站点将有大量请求,因此算法不应太慢。

我的问题是我发现的所有算法都会产生不需要的字符(如 +/=)

这是我想要实现的一个例子:

www.domain.com/?id=1844

www.domain.com/?id=3GQ5DTL3oVd91WsGj74gcQ

混淆后的参数应仅包含a-z 和A-Z 以及0-9 字符。

我知道我可以使用 base64 进行加密,但这会生成不需要的字符,例如 /=+

知道可以使用什么算法吗?

更新:我知道 UrlEncoding ,我想避免对字符串进行编码。因为这会在 url 中生成类似 %F2 或 %B2 的字符。

最佳答案

您可以使用三重 DES 使用窄 block 密码对值进行编码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace ConsoleApplication1 {
class Program {
static string ToHex(byte[] value) {
StringBuilder sb = new StringBuilder();
foreach (byte b in value)
sb.AppendFormat("{0:x2}", b);
return sb.ToString();
}
static string Encode(long value, byte[] key) {
byte[] InputBuffer = new byte[8];
byte[] OutputBuffer;
unsafe {
fixed (byte* pInputBuffer = InputBuffer) {
((long*)pInputBuffer)[0] = value;
}
}
TripleDESCryptoServiceProvider TDes = new TripleDESCryptoServiceProvider();
TDes.Mode = CipherMode.ECB;
TDes.Padding = PaddingMode.None;
TDes.Key = key;

using (ICryptoTransform Encryptor = TDes.CreateEncryptor()) {
OutputBuffer = Encryptor.TransformFinalBlock(InputBuffer, 0, 8);
}
TDes.Clear();

return ToHex(OutputBuffer);
}
static long Decode(string value, byte[] key) {
byte[] InputBuffer = new byte[8];
byte[] OutputBuffer;

for (int i = 0; i < 8; i++) {
InputBuffer[i] = Convert.ToByte(value.Substring(i * 2, 2), 16);
}

TripleDESCryptoServiceProvider TDes = new TripleDESCryptoServiceProvider();
TDes.Mode = CipherMode.ECB;
TDes.Padding = PaddingMode.None;
TDes.Key = key;

using (ICryptoTransform Decryptor = TDes.CreateDecryptor()) {
OutputBuffer = Decryptor.TransformFinalBlock(InputBuffer, 0, 8);
}
TDes.Clear();

unsafe {
fixed (byte* pOutputBuffer = OutputBuffer) {
return ((long*)pOutputBuffer)[0];
}
}
}
static void Main(string[] args) {
long NumberToEncode = (new Random()).Next();
Console.WriteLine("Number to encode = {0}.", NumberToEncode);
byte[] Key = new byte[24];
(new RNGCryptoServiceProvider()).GetBytes(Key);
Console.WriteLine("Key to encode with is {0}.", ToHex(Key));
string EncodedValue = Encode(NumberToEncode, Key);
Console.WriteLine("The encoded value is {0}.", EncodedValue);
long DecodedValue = Decode(EncodedValue, Key);
Console.WriteLine("The decoded result is {0}.", DecodedValue);
}
}
}

输出应该是这样的:

Number to encode = 873435734.
Key to encode with is 38137b6a7aa49cc6040c4297064fdb4461c79a895f40b4d1.
The encoded value is 43ba3fb809a47b2f.
The decoded result is 873435734.

请注意,编码后的值只有 16 个字符宽。

如果您真的很担心滥用,那么可以以类似的方式使用 AES。在下一个示例中,我切换到 AES 并将 64 位 ID 编号写入 block 的两侧。如果它没有在两侧使用相同的值进行解码,那么它就会被拒绝。这可以防止人们写入随机数字。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace ConsoleApplication1 {
class Program {
static string ToHex(byte[] value) {
StringBuilder sb = new StringBuilder();
foreach (byte b in value)
sb.AppendFormat("{0:x2}", b);
return sb.ToString();
}
static string Encode(long value, byte[] key) {
byte[] InputBuffer = new byte[16];
byte[] OutputBuffer;
unsafe {
fixed (byte* pInputBuffer = InputBuffer) {
((long*)pInputBuffer)[0] = value;
((long*)pInputBuffer)[1] = value;
}
}
AesCryptoServiceProvider Aes = new AesCryptoServiceProvider();
Aes.Mode = CipherMode.ECB;
Aes.Padding = PaddingMode.None;
Aes.Key = key;

using (ICryptoTransform Encryptor = Aes.CreateEncryptor()) {
OutputBuffer = Encryptor.TransformFinalBlock(InputBuffer, 0, 16);
}
Aes.Clear();

return ToHex(OutputBuffer);
}
static bool TryDecode(string value, byte[] key, out long result) {
byte[] InputBuffer = new byte[16];
byte[] OutputBuffer;

for (int i = 0; i < 16; i++) {
InputBuffer[i] = Convert.ToByte(value.Substring(i * 2, 2), 16);
}

AesCryptoServiceProvider Aes = new AesCryptoServiceProvider();
Aes.Mode = CipherMode.ECB;
Aes.Padding = PaddingMode.None;
Aes.Key = key;

using (ICryptoTransform Decryptor = Aes.CreateDecryptor()) {
OutputBuffer = Decryptor.TransformFinalBlock(InputBuffer, 0, 16);
}
Aes.Clear();

unsafe {
fixed (byte* pOutputBuffer = OutputBuffer) {
//return ((long*)pOutputBuffer)[0];
if (((long*)pOutputBuffer)[0] == ((long*)pOutputBuffer)[1]) {
result = ((long*)pOutputBuffer)[0];
return true;
}
else {
result = 0;
return false;
}
}
}
}
static void Main(string[] args) {
long NumberToEncode = (new Random()).Next();
Console.WriteLine("Number to encode = {0}.", NumberToEncode);
byte[] Key = new byte[24];
(new RNGCryptoServiceProvider()).GetBytes(Key);
Console.WriteLine("Key to encode with is {0}.", ToHex(Key));
string EncodedValue = Encode(NumberToEncode, Key);
Console.WriteLine("The encoded value is {0}.", EncodedValue);
long DecodedValue;
bool Success = TryDecode(EncodedValue, Key, out DecodedValue);
if (Success) {
Console.WriteLine("Successfully decoded the encoded value.");
Console.WriteLine("The decoded result is {0}.", DecodedValue);
}
else
Console.WriteLine("Failed to decode encoded value. Invalid result.");
}
}
}

结果现在应该是这样的:

Number to encode = 1795789891.
Key to encode with is 6c90323644c841a00d40d4407e23dbb2ab56530e1a4bae43.
The encoded value is 731fceec2af2fcc2790883f2b79e9a01.
Successfully decoded the encoded value.
The decoded result is 1795789891.

另请注意,由于我们现在使用了更宽的分组密码,因此编码值现在为 32 个字符宽。

关于c# - 查询字符串参数混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3569783/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com