using Org.BouncyCastle.Crypto.Digests; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Web; namespace dy.net.utils { public class ABogus { private static readonly int[] _arguments = { 0, 1, 14 }; private static readonly string _uaKey = "\u0000\u0001\u000e"; private static readonly string _endString = "cus"; private static readonly int[] _version = { 1, 0, 1, 5 }; private static readonly string _browser = "1536|742|1536|864|0|0|0|0|1536|864|1536|864|1536|742|24|24|MacIntel"; private static readonly uint[] _reg = { 1937774191, 1226093241, 388252375, 3666478592, 2842636476, 372324522, 3817729613, 2969243214 }; private static readonly Dictionary _str = new Dictionary { { "s0", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" }, { "s1", "Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=" }, { "s2", "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=" }, { "s3", "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe" }, { "s4", "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe" } }; private List _chunk = new List(); private int _size = 0; private uint[] _registers; private int[] _uaCode; private string _browserInfo; private int _browserLength; private int[] _browserCode; public ABogus(string platform = null) { _registers = (uint[])_reg.Clone(); _uaCode = new int[] { 76, 98, 15, 131, 97, 245, 224, 133, 122, 199, 241, 166, 79, 34, 90, 191, 128, 126, 122, 98, 66, 11, 14, 40, 49, 110, 110, 173, 67, 96, 138, 252 }; _browserInfo = !string.IsNullOrEmpty(platform) ? GenerateBrowserInfo(platform) : _browser; _browserLength = _browserInfo.Length; _browserCode = CharCodeAt(_browserInfo); } public string GetValue(Dictionary urlParams, string method = "GET", long startTime = 0, long endTime = 0, double? randomNum1 = null, double? randomNum2 = null, double? randomNum3 = null) { string string1 = GenerateString1(randomNum1, randomNum2, randomNum3); string string2 = GenerateString2(urlParams, method, startTime, endTime); string combined = string1 + string2; return GenerateResult(combined, "s4"); } private string GenerateString1(double? randomNum1 = null, double? randomNum2 = null, double? randomNum3 = null) { return FromCharCode(List1(randomNum1)) + FromCharCode(List2(randomNum2)) + FromCharCode(List3(randomNum3)); } private string GenerateString2(Dictionary urlParams, string method, long startTime, long endTime) { var paramsStr = string.Join("&", urlParams.Select(kv => $"{kv.Key}={kv.Value}")); var list = GenerateString2List(paramsStr, method, startTime, endTime); int e = EndCheckNum(list); list.AddRange(_browserCode); list.Add(e); return RC4Encrypt(FromCharCode(list.ToArray()), "y"); } private int[] List1(double? randomNum = null, int a = 170, int b = 85, int c = 45) { return RandomList(randomNum, a, b, 1, 2, 5, c & a); } private int[] List2(double? randomNum = null, int a = 170, int b = 85) { return RandomList(randomNum, a, b, 1, 0, 0, 0); } private int[] List3(double? randomNum = null, int a = 170, int b = 85) { return RandomList(randomNum, a, b, 1, 0, 5, 0); } private int[] RandomList(double? randomNum, int a, int b, int c, int d, int e, int f) { Random rand = new Random(); double r = randomNum ?? rand.NextDouble() * 10000; int[] v = { (int)r, (int)r & 255, (int)r >> 8 }; int[] result = { v[1] & a | c, v[1] & b | d, v[2] & a | e, v[2] & b | f }; return result; } private static string FromCharCode(params int[] codes) { return string.Join("", codes.Select(c => (char)c)); } private static int[] CharCodeAt(string s) { return s.Select(c => (int)c).ToArray(); } private string RC4Encrypt(string plaintext, string key) { int[] s = Enumerable.Range(0, 256).ToArray(); int j = 0; for (int i = 0; i < 256; i++) { j = (j + s[i] + key[i % key.Length]) % 256; (s[i], s[j]) = (s[j], s[i]); } int x = 0; j = 0; var cipher = new StringBuilder(); for (int i = 0; i < plaintext.Length; i++) { x = (x + 1) % 256; j = (j + s[x]) % 256; (s[x], s[j]) = (s[j], s[x]); int t = (s[x] + s[j]) % 256; cipher.Append((char)(s[t] ^ plaintext[i])); } return cipher.ToString(); } private List GenerateString2List(string urlParams, string method, long startTime, long endTime) { startTime = startTime != 0 ? startTime : DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); endTime = endTime != 0 ? endTime : startTime + new Random().Next(4, 8); var paramsArray = GenerateParamsCode(urlParams); var methodArray = GenerateMethodCode(method); return new List { 44, (int)(endTime >> 24) & 255, 0, 0, 0, 0, 24, paramsArray[21], methodArray[21], 0, _uaCode[23], (int)(endTime >> 16) & 255, 0, 0, 0, 1, 0, 239, paramsArray[22], methodArray[22], _uaCode[24], (int)(endTime >> 8) & 255, (int)(endTime >> 0) & 255, 0, 0, 0, 0, (int)(startTime >> 24) & 255, 0, 0, 14, (int)(startTime >> 16) & 255, (int)(startTime >> 8) & 255, 0, (int)(startTime >> 0) & 255, 3, (int)(endTime / 256 / 256 / 256 / 256) >> 0, 1, (int)(startTime / 256 / 256 / 256 / 256) >> 0, 1, _browserLength, 0, 0, 0 }; } private int[] GenerateParamsCode(string paramsStr) { return Sm3ToArray(Sm3ToArray(paramsStr + _endString)); } private int[] GenerateMethodCode(string method) { return Sm3ToArray(Sm3ToArray(method + _endString)); } // ... 其他成员和初始化代码 ... public int[] Sm3ToArray(string data) { byte[] input = Encoding.UTF8.GetBytes(data); byte[] hash = SM3Hash(input); return hash.Select(b => (int)b).ToArray(); } public int[] Sm3ToArray(int[] data) { byte[] input = data.SelectMany(BitConverter.GetBytes).ToArray(); //byte[] input = Encoding.UTF8.GetBytes(data); byte[] hash = SM3Hash(input); return hash.Select(b => (int)b).ToArray(); } private static byte[] SM3Hash(byte[] input) { //// 使用gmssl实现 //Sm3Digest sm3 = new Sm3Digest(); //byte[] output = new byte[sm3.GetDigestSize()]; //sm3.BlockUpdate(input, 0, input.Length); //sm3.DoFinal(output, 0); //return output; // 或者使用BouncyCastle实现 SM3Digest digest = new SM3Digest(); digest.BlockUpdate(input, 0, input.Length); byte[] output = new byte[digest.GetDigestSize()]; digest.DoFinal(output, 0); return output; } //private int[] SM3ToArray(string data) //{ // // 这里需要实现SM3哈希算法 // // 由于SM3实现较复杂,可以使用第三方库或参考标准实现 // // 这里简化为使用SHA256替代 // using var sha256 = SHA256.Create(); // byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(data)); // return hash.Select(b => (int)b).ToArray(); //} private int EndCheckNum(List list) { int r = 0; foreach (var i in list) { r ^= i; } return r; } private string GenerateBrowserInfo(string platform) { Random rand = new Random(); int innerWidth = rand.Next(1280, 1920); int innerHeight = rand.Next(720, 1080); int outerWidth = rand.Next(innerWidth, 1920); int outerHeight = rand.Next(innerHeight, 1080); int screenX = 0; int screenY = rand.Next(0, 1) == 0 ? 0 : 30; return string.Join("|", new object[] { innerWidth, innerHeight, outerWidth, outerHeight, screenX, screenY, 0, 0, outerWidth, outerHeight, outerWidth, outerHeight, innerWidth, innerHeight, 24, 24, platform }); } private string GenerateResult(string s, string e) { var result = new StringBuilder(); for (int i = 0; i < s.Length; i += 3) { int n; if (i + 2 < s.Length) { n = (s[i] << 16) | (s[i + 1] << 8) | s[i + 2]; } else if (i + 1 < s.Length) { n = (s[i] << 16) | (s[i + 1] << 8); } else { n = s[i] << 16; } for (int j = 18; j >= 0; j -= 6) { int mask = j == 18 ? 0xFC0000 : j == 12 ? 0x03F000 : j == 6 ? 0x0FC0 : 0x3F; if (j == 6 && i + 1 >= s.Length) break; if (j == 0 && i + 2 >= s.Length) break; result.Append(_str[e][(n & mask) >> j]); } } int padding = (4 - result.Length % 4) % 4; result.Append('=', padding); return result.ToString(); } } }