Register for your free account! | Forgot your password?

You last visited: Today at 14:42

  • Please register to post and access all features, it's quick, easy and FREE!


AccountServer has new cryptography.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Mar 2014
Posts: 16
Received Thanks: 4
AccountServer has new cryptography.

greats ,

as the title said on patch 6719 conquer update the accountserver packets 1542 and 1637, the packets has new cryptography which cannot got the info from it
all strings has been encrypted .. i guess it's with RC5 , they using seed from packet 1059 and resend it in packet 1542 (encrypted seed).

so anyone know anything about that ? and we can do that or will not upgrade our Private Servers to this patch or higher ?

sorry for my bad english ,
thanks for your time



Ahmed El5WaGa is offline  
Old 06/13/2018, 06:59   #2
 
elite*gold: 12
Join Date: Jul 2011
Posts: 6,963
Received Thanks: 3,329
Quote:
Originally Posted by Ahmed El5WaGa View Post
greats ,

as the title said on patch 6719 conquer update the accountserver packets 1542 and 1637, the packets has new cryptography which cannot got the info from it
all strings has been encrypted .. i guess it's with RC5 , they using seed from packet 1059 and resend it in packet 1542 (encrypted seed).

so anyone know anything about that ? and we can do that or will not upgrade our Private Servers to this patch or higher ?

sorry for my bad english ,
thanks for your time
You'd be wrong, and two or three pretty massive cryptography changes behind. Don't even try, trust me. Just detour the client functions to use RC5 instead, like all private servers beyond 5532+ do. It's not worth reverse engineering.


Spirited is offline  
Old 06/13/2018, 08:08   #3
 
elite*gold: 0
Join Date: Mar 2014
Posts: 16
Received Thanks: 4
Quote:
Originally Posted by Spirited View Post
You'd be wrong, and two or three pretty massive cryptography changes behind. Don't even try, trust me. Just detour the client functions to use RC5 instead, like all private servers beyond 5532+ do. It's not worth reverse engineering.
greets ,

firstly thanks for replying ,

you mean to don't try to reverse it ?
you said it's just " detour " , that mean if i'm worked hard will got it but will wast my time that's true ..
"It's not worth reverse engineering"
you mean i can use something with my injector to make it easy with login it's true too ..

but i'm not thinking with this dead game 100 percent .. i'm learning from the worst problem may i found.

sorry for my bad english
Ahmed El5WaGa is offline  
Old 06/13/2018, 17:20   #4
 
elite*gold: 12
Join Date: Jul 2011
Posts: 6,963
Received Thanks: 3,329
Quote:
Originally Posted by Ahmed El5WaGa View Post
greets ,

firstly thanks for replying ,

you mean to don't try to reverse it ?
you said it's just " detour " , that mean if i'm worked hard will got it but will wast my time that's true ..
"It's not worth reverse engineering"
you mean i can use something with my injector to make it easy with login it's true too ..

but i'm not thinking with this dead game 100 percent .. i'm learning from the worst problem may i found.

sorry for my bad english
No... I mean what I say by using words.... Detour functions, as in detour functions. Google it, or don't. Definitely doesn't mean "if I'm worked hard will got it". It means give up completely and inject RC5. "Not worth reverse engineering", as in waste of time attempting to reverse engineer. Not, go learn the problem if you want to learn. It's a very complicated thing to reverse engineer, and doesn't make sense to do at all if you just want a private server, so don't.


Spirited is offline  
Old 06/13/2018, 17:44   #5
 
elite*gold: 0
Join Date: Mar 2014
Posts: 16
Received Thanks: 4
Quote:
Originally Posted by Spirited View Post
No... I mean what I say by using words.... Detour functions, as in detour functions. Google it, or don't. Definitely doesn't mean "if I'm worked hard will got it". It means give up completely and inject RC5. "Not worth reverse engineering", as in waste of time attempting to reverse engineer. Not, go learn the problem if you want to learn. It's a very complicated thing to reverse engineer, and doesn't make sense to do at all if you just want a private server, so don't.
greets,

thanks for replying

"Google it"
i'll
but i want to make sure of the type of encryption !!
if you know what's the type and sure of that i'll try and that's will save some time for me ..

i'm want private server of course but will try to got that encryption

sorry for my bad english..
Ahmed El5WaGa is offline  
Old 06/14/2018, 04:04   #6
 
elite*gold: 12
Join Date: Jul 2011
Posts: 6,963
Received Thanks: 3,329
Quote:
Originally Posted by Ahmed El5WaGa View Post
greets,

thanks for replying

"Google it"
i'll
but i want to make sure of the type of encryption !!
if you know what's the type and sure of that i'll try and that's will save some time for me ..

i'm want private server of course but will try to got that encryption

sorry for my bad english..
I was trying to save you some time by not telling you, but it you're so insistent on trying to reverse it, or much more likely pay someone to reverse it, then good luck. It's a custom, off-spec SRP6 implementation. It's changed twice now. Enjoy.
Spirited is offline  
Old 06/20/2018, 11:04   #7
 
elite*gold: 0
Join Date: Dec 2012
Posts: 1,593
Received Thanks: 825
Quote:
Originally Posted by Ahmed El5WaGa View Post
greets,

thanks for replying

"Google it"
i'll
but i want to make sure of the type of encryption !!
if you know what's the type and sure of that i'll try and that's will save some time for me ..

i'm want private server of course but will try to got that encryption

sorry for my bad english..
A good place to start would be this:

Code:
using System;
using System.Numerics;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace SRP6
{
    public class Srp6
    {
        #region Modulus(N), salt, generator(g), multiplier(k), Identity Hash
        public BigInteger Modulus
        {
            get;
            private set;
        }

        public BigInteger Salt
        {
            get;
            private set;
        }

        public BigInteger Generator
        {
            get;
            private set;
        }

        public BigInteger Multiplier
        {
            get;
            private set;
        }

        public byte[] IdentityHash
        {
            get;
            private set;
        }
        #endregion

        #region Server calculated properties
        public BigInteger SaltedIdentityHash
        {
            get;
            private set;
        }

        public BigInteger Scrambler
        {
            get;
            private set;
        }

        public BigInteger Verifier
        {
            get;
            private set;
        }
        #endregion

        #region Common properties
        public BigInteger SessionKey
        {
            get;
            private set;
        }

        public BigInteger PrivateKey
        {
            get;
            private set;
        }

        public BigInteger PublicKey
        {
            get;
            private set;
        }

        public bool IsServerInstance
        {
            get;
            private set;
        }
        #endregion

        #region Encryption/Decryption properties
        /// <summary>
        /// The initial vector used for the AES Decrypt/Encrypt methods
        /// </summary>
        public string InitialVector
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the hash algorithm.
        /// </summary>
        public string HashAlgorithm
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the password iterations.
        /// </summary>
        public int PasswordIterations
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the size of the key.
        /// </summary>
        public int KeySize
        {
            get;
            private set;
        }
        #endregion

        #region Constructors
        private Srp6(string initialVector, string modulus, int generator, byte[] identityHash)
        {
            HashAlgorithm = "SHA1";
            PasswordIterations = 2;
            KeySize = 256;
            InitialVector = initialVector;

            IdentityHash = identityHash;
            Modulus = BigIntegerExtensions.CreateBigInteger(modulus, 16);
            Generator = BigIntegerExtensions.CreateBigInteger("" + generator, 10);
            Multiplier = BigIntegerExtensions.CreateBigInteger("3", 10);
        }

        // Server Constructor, Radix 16 strings, 256-bit predef values
        public Srp6(byte[] identityHash, string modulus, int generator, int saltBits,
            int scramblerBits, string initialVector = "OFRna73m*aze01xY")
            : this(initialVector, modulus, generator, identityHash)
        {
            // This SRP6 instance is a server instance
            IsServerInstance = true;

            // Generate the Salt
            Salt = BigIntegerExtensions.CreateBigInteger(saltBits, new Random());

            // Set the salted identity hash, scrambler, and verifier
            Scrambler = BigIntegerExtensions.CreateBigInteger(scramblerBits, new Random());
            SaltedIdentityHash = Salt.CreateSaltedIdentityHash(identityHash);
            Verifier = Generator.ModPow(SaltedIdentityHash, Modulus);

            // Random 128 bit number that is a probable prime
            PrivateKey = BigIntegerExtensions.GeneratePseudoPrime(128, 100, new Random());

            // kv + g^b  (mod N)
            PublicKey = Multiplier.Multiply(Verifier).Add(Generator.ModPow(PrivateKey, Modulus));
        }

        // Client Constructor, salt not generated by client
        public Srp6(byte[] identityHash, String modulus, int generator,
            String salt, string initialVector = "OFRna73m*aze01xY")
            : this(initialVector, modulus, generator, identityHash)
        {
            // This SRP6 instance is a client instance
            IsServerInstance = false;

            // Convert the salt string to a BigInteger
            Salt = BigIntegerExtensions.CreateBigInteger(salt, 16);

            // Set the salted identity hash
            SaltedIdentityHash = Salt.CreateSaltedIdentityHash(identityHash);                

            // Generate a pseudo prime to use for the private key
            PrivateKey = BigIntegerExtensions.GeneratePseudoPrime(128, 100, new Random());

            // g^a (mod N)
            PublicKey = Generator.ModPow(PrivateKey, Modulus);
        }
        #endregion

        #region Set Session Key
        public void SetSessionKey(String pubKeyString, String scrambler = null)
        {
            BigInteger pubKey = BigIntegerExtensions.CreateBigInteger(pubKeyString, 16);
            if (IsServerInstance)       // Server SessionKey
            {
                // (Av^u) ^ b (mod N)
                SessionKey = pubKey.Multiply(Verifier.ModPow(Scrambler, Modulus)).ModPow(PrivateKey, Modulus);
            }
            else                        // Client SessionKey
            {
                Scrambler = BigIntegerExtensions.CreateBigInteger(scrambler, 16);
                BigInteger temp = PrivateKey.Add(Scrambler.Multiply(SaltedIdentityHash));
                SessionKey = pubKey.Subtract((Generator.ModPow(SaltedIdentityHash, Modulus))
                                             .Multiply(Multiplier)).ModPow(temp, Modulus);
            }
        }
        #endregion

        #region Encryption methods
        /// <summary>
        /// Encrypts a string
        /// </summary>
        /// <param name="plainText">Text to be encrypted</param>
        /// <returns>The encrypted string</returns>
        public string Encrypt(string plainText)
        {
            if(string.IsNullOrEmpty(plainText))
                return "";
            var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            var cipherTextBytes = Encrypt(plainTextBytes);
            return Convert.ToBase64String(cipherTextBytes);
        }

        /// <summary>
        /// Encrypt the specified stream. This should be called in a using statement.
        /// </summary>
        /// <param name='stream'>Stream to encrypt</param>
        /// <returns>An encrypted memory stream</returns>
        public Stream Encrypt(Stream stream)
        {
            var results = new byte[stream.Length];
            stream.Read(results, 0, results.Length);
            byte[] encryptedBytes = Encrypt(results);
            return new MemoryStream(encryptedBytes, false);
        }

        /// <summary>
        /// Encrypt the specified plainTextBytes
        /// </summary>
        /// <param name='plainTextBytes'>Plain text bytes</param>
        /// <returns>Encrypted text bytes</returns>
        public byte[] Encrypt(byte[] plainTextBytes)
        {
            string password = SessionKey.ToHexString();
            string salt = Salt.ToHexString();
            if(plainTextBytes == null)
                return null;
            byte[] initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
            var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, HashAlgorithm, PasswordIterations);
            byte[] keyBytes = derivedPassword.GetBytes(KeySize / 8);
            var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
            byte[] cipherTextBytes;
            using(var encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes))
            {
                using(var memStream = new MemoryStream())
                {
                    using(var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                        cryptoStream.FlushFinalBlock();
                        cipherTextBytes = memStream.ToArray();
                        memStream.Close();
                        cryptoStream.Close();
                    }
                }
            }
            symmetricKey.Clear();
            return cipherTextBytes;
        }
        #endregion

        #region Decryption methods
        /// <summary>
        /// Decrypts a string
        /// </summary>
        /// <param name="cipherText">Text to be decrypted</param>
        /// <returns>The decrypted string</returns>
        public string Decrypt(string cipherText)
        {
            if(string.IsNullOrEmpty(cipherText))
                return "";
            int byteCount;
            byte[] plainTextBytes = Decrypt(Convert.FromBase64String(cipherText), out byteCount);
            return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
        }

        /// <summary>
        /// Decrypt the specified stream. This should be called in a using statement.
        /// </summary>
        /// <param name='stream'>Stream to decrypt</param>
        /// <returns>A decrypted memory stream</returns>
        public Stream Decrypt(Stream stream)
        {
            var results = new byte[stream.Length];
            stream.Read(results, 0, results.Length);
            byte[] decryptedBytes = Decrypt(results);
            return new MemoryStream(decryptedBytes, false);
        }

        /// <summary>
        /// Decrypt the specified cipherTextBytes.
        /// </summary>
        /// <param name='cipherTextBytes'>Cipher text bytes</param>
        /// <returns>Decrypted text bytes</returns>
        public byte[] Decrypt(byte[] cipherTextBytes)
        {
            if(cipherTextBytes == null)
                return null;
            int byteCount;
            byte[] decryptedArray = Decrypt(cipherTextBytes, out byteCount);
            return decryptedArray.SubArray(0, byteCount);
        }

        private byte[] Decrypt(byte[] cipherTextBytes, out int byteCount)
        {
            string password = SessionKey.ToHexString();
            string salt = Salt.ToHexString();
            if(cipherTextBytes == null)
            {
                byteCount = 0;
                return null;
            }
            byte[] initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
            var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, HashAlgorithm, PasswordIterations);
            var keyBytes = derivedPassword.GetBytes(KeySize / 8);
            var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
            var plainTextBytes = new byte[cipherTextBytes.Length];
            using(var decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes))
            {
                using(var memStream = new MemoryStream(cipherTextBytes))
                {
                    using(var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                    {

                        byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                        memStream.Close();
                        cryptoStream.Close();
                    }
                }
            }
            symmetricKey.Clear();
            return plainTextBytes;
        }
        #endregion
    }
}
Code:
using System;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;

namespace SRP6
{
    /// <summary>
    /// Srp6 extenstion methods
    /// </summary>
    public static class OtherExtensions
    {
        /// <summary>
        /// Create a BigInteger from a hash of the salt and identity hash (SaltedIdentityHash).
        /// </summary>
        /// <param name='salt'>The salt</param>
        /// <param name='identityHash'>The identity hash</param>
        public static BigInteger CreateSaltedIdentityHash(this BigInteger salt, byte[] identityHash)
        {
            return BigIntegerExtensions.CreateBigInteger(
                Concatenate(salt.ToByteArray(), identityHash).Sha1Hash().ToHexString(), 16);
        }

        /// <summary>
        /// This is a SHA1 hash extension method.
        /// </summary>
        /// <returns>The hash</returns>
        /// <param name='arg1'>The byte array</param>
        public static byte[] Sha1Hash(this byte[] arg1)
        {
            try
            {
                if ((arg1 == null) || (arg1.Length == 0))
                    throw new InvalidOperationException("arg1 can not be null or have a length of zero.");
                SHA1 sha = new SHA1CryptoServiceProvider();
                sha.ComputeHash(arg1);
                return sha.Hash;
            }
            catch(Exception e)
            {
                Console.WriteLine("Sha1Hash: " + e.Message);
                return null;
            }
        }

        /// <summary>
        /// Concatenates multiple byte arrays
        /// </summary>
        /// <returns>The concatenated array</returns>
        /// <param name='arrays'>The source arrays</param>
        private static byte[] Concatenate(params byte[][] arrays)
        {
            var length = arrays.Where(array => array != null).Sum(array => array.Length) + 1;
            var result = new byte[length];
            length = 0;
            foreach (var array in arrays.Where(array => array != null))
            {
                Array.Copy(array, 0, result, length, array.Length);
                length += array.Length;
            }
            return result;
        }

        /// <summary>
        /// Extracts an array from an array
        /// </summary>
        /// <returns>The new array.</returns>
        /// <param name='sourceArray'>The source array</param>
        /// <param name='offset'>The offset to start building the new array</param>
        /// <param name='length'>The length of the new array.</param>
        public static T[] SubArray<T>(this T[] sourceArray, int offset, int length)
        {
            var result = new T[length];
            Array.Copy(sourceArray, offset, result, 0, length);
            return result;
        }

        /// <summary>
        /// Converts a byte array into a hex formatted text string.
        /// </summary>
        /// <returns>Hex formatted text string</returns>
        /// <param name="byteArray">The byte array to convert</param>
        public static string ToHexString(this byte[] byteArray)
        {
            if (byteArray == null)
                return "";
            string result = "";
            for (int i = byteArray.Length - 1; i >= 0; i--)
                result += byteArray[i].ToString("X2");
            return result;
        }

        public static string ToString(this byte[] totalArray, int offset, int length)
        {
            byte[] array = SubArray(totalArray, offset, length);
            return Encoding.ASCII.GetString(array);
        }

    }
}
Code:
using System;
using System.Numerics;

namespace SRP6
{
    /// <summary>
    /// This class adds additional support for .NET BigInteger.
    /// </summary>
    public static class BigIntegerExtensions
    {
        #region Constants
        public static readonly BigInteger Two = new BigInteger(2);
        public static readonly uint[] SmallPrimes = {
            2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
            73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
            157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,
            239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
            331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
            421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
            509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607,
            613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
            709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811,
            821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
            919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,

            1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087,
            1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181,
            1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279,
            1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
            1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471,
            1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
            1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637,
            1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
            1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867,
            1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973,
            1979, 1987, 1993, 1997, 1999, 
        
            2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089,
            2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207,
            2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
            2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389,
            2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
            2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621,
            2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707,
            2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797,
            2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
            2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
            
            3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109,
            3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
            3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329,
            3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449,
            3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539,
            3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631,
            3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733,
            3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
            3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943,
            3947, 3967, 3989,
            
            4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091,
            4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
            4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289,
            4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423,
            4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523,
            4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649,
            4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759,
            4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
            4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987,
            4993, 4999,
            
            5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101,
            5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 
            5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351,
            5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449,
            5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563,
            5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669,
            5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
            5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869,
            5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987
        };
        #endregion

        #region Additional construction functions
        /// <summary>
        /// Create a BigInteger from the specified text and convertBase.
        /// </summary>
        /// <param name='text'>A text string representing the number</param>
        /// <param name='convertBase'>The convertion base</param>
        public static BigInteger CreateBigInteger(string text, int convertBase)
        {
            if (convertBase == 16)
            {
                var isEvenLength = (text.Length % 2 == 0);
                var length = (text.Length / 2) + (isEvenLength ? 0 : 1);
                var result = new byte[length + 1];
                for (var i = 0; i < length; i++)
                {
                    var j = text.Length - (i * 2) - 1;
                    var ch1 = '0';
                    if (j > 0)
                        ch1 = text[j - 1];
                    var b = GetHexadecimalByte(ch1, text[j]);
                    result[i] = b;
                }
                result[length] = 0;
                return new BigInteger(result).MakePositive();
            }
            if (convertBase == 10)
                return BigInteger.Parse(text).MakePositive();
            throw new Exception("Unsupported conversion base");
        }

        /// <summary>
        /// Create a random BigInteger with the specified number of bits.
        /// </summary>
        /// <param name='numberOfBits'>Number of bits</param>
        /// <param name='random'>The Random instance for generating the BigInteger</param>
        public static BigInteger CreateBigInteger(int numberOfBits, Random random)
        {
            var numberOfFullBytes = numberOfBits / 8;
            var numberOfRemainingBits = numberOfBits % 8;
            var numberOfBytes = numberOfFullBytes +(numberOfRemainingBits > 0 ? 1 : 0);

            // This retry loop was added to handle weird exceptions from Mono's version of the BigInteger class
            // ToDo: Verify exactly what is causing this problem
            for (var i = 0; i < 3; i++)
            {
                try
                {
                    var randomBytes = new byte[numberOfBytes];
                    random.NextBytes(randomBytes);

                    // Mask off unused bits
                    if (numberOfRemainingBits > 0)
                        randomBytes[randomBytes.Length - 1] =
                            MaskBits(randomBytes[randomBytes.Length - 1], 8 - numberOfRemainingBits);
                    
                    // Make unsigned and return result
                    return new BigInteger(randomBytes).MakePositive();
                }
                catch (Exception)
                {
                    // If it's the last retry iteration, just throw the exception
                    if (i == 2)
                        throw;
                }
            }

            // This should be unreachable code
            throw new Exception("Should not happen");
        }
        #endregion

        #region Instance extensions for BigInteger static math functions
        public static BigInteger ModPow(this BigInteger bigInt, BigInteger exponent,
            BigInteger modulus)
        {
            return BigInteger.ModPow(bigInt, exponent, modulus);
        }

        public static BigInteger Multiply(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Multiply(bigInt, value);
        }

        public static BigInteger Add(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Add(bigInt, value);
        }

        public static BigInteger Subtract(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Subtract(bigInt, value);
        }

        public static BigInteger Divide(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Divide(bigInt, value);
        }

        public static BigInteger Gcd(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.GreatestCommonDivisor(bigInt, value);
        }
        #endregion

        #region Bit masking and BitCount
        private static byte MaskBits(byte b, int bitCount)
        {
            if (bitCount == 7)
                return (byte)(b & 1);
            if (bitCount == 6)
                return (byte)(b & 3);
            if(bitCount == 5)
                return (byte)(b & 7);
            if(bitCount == 4)
                return (byte)(b & 15);
            if(bitCount == 3)
                return (byte)(b & 31);
            if(bitCount == 2)
                return (byte)(b & 63);
            if(bitCount == 1)
                return (byte)(b & 127);
            throw new ArgumentException("bitCount is not from 1-7");
        }

        public static int BitCount(this BigInteger bigInt)
        {
            byte[] bytes = bigInt.ToUnsignedByteArray();
            return (bytes.Length * sizeof(byte));
        }
        #endregion

        #region Prime number testing
        // Modified from http://www.codeproject.com/Articles/2728/C-BigInteger-Class for use with the BigInteger
        public static bool RabinMillerTest(this BigInteger thisVal, int confidence)
        {
            byte[] bytes = thisVal.ToUnsignedByteArray();
            if (bytes.Length == 1)
            {
                // test small numbers
                if (bytes[0] == 0 || bytes[0] == 1)
                    return false;
                if (bytes[0] == 2 || bytes[0] == 3)
                    return true;
            }

            if ((bytes[0] & 0x1) == 0)     // even numbers
                return false;

            // calculate values of s and t
            BigInteger pSub1 = thisVal - (new BigInteger(1));
            byte[] pSub1Bytes = pSub1.ToUnsignedByteArray();
            int s = 0;

            for (var index = 0; index < pSub1Bytes.Length; index++)
            {
                uint mask = 0x01;

                for (var i = 0; i < 32; i++)
                {
                    if ((pSub1Bytes[index] & mask) != 0)
                    {
                        index = pSub1Bytes.Length;      // to break the outer loop
                        break;
                    }
                    mask <<= 1;
                    s++;
                }
            }

            BigInteger t = pSub1 >> s;

            int bits = thisVal.BitCount();
            BigInteger a = new BigInteger().MakePositive();
            var rand = new Random();

            for (var round = 0; round < confidence; round++)
            {
                var done = false;

                while (!done)        // generate a < n
                {
                    int testBits = 0;

                    // make sure "a" has at least 2 bits
                    while (testBits < 2)
                        testBits =(int)(rand.NextDouble() * bits);

                    a = CreateBigInteger(testBits, rand);
                    byte[] aBytes = a.ToUnsignedByteArray();

                    // make sure "a" is not 0
                    if (aBytes.Length > 1 ||(aBytes.Length == 1 && aBytes[0] != 1))
                        done = true;
                }

                // check whether a factor exists(fix for version 1.03)
                BigInteger gcdTest = a.Gcd(thisVal);
                byte[] gcdBytes = gcdTest.ToUnsignedByteArray();
                if (gcdBytes.Length == 1 && gcdBytes[0] != 1)
                    return false;

                BigInteger b = a.ModPow(t, thisVal);
                byte[] bBytes = b.ToUnsignedByteArray();

                var result = bBytes.Length == 1 && bBytes[0] == 1;

                for (var j = 0; result == false && j < s; j++)
                {
                    if (b == pSub1)         // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1
                    {
                        result = true;
                        break;
                    }

                    b =(b * b) % thisVal;
                }

                if (result == false)
                    return false;
            }
            return true;
        }

        public static bool IsProbablePrime(this BigInteger thisVal, int confidence)
        {
            // test for divisibility by the smaller primes
            for (var p = 0; p < SmallPrimes.Length; p++)
            {
                BigInteger divisor = SmallPrimes[p];

                if (divisor >= thisVal)
                    break;

                BigInteger resultNum = thisVal % divisor;
                if (resultNum == BigInteger.Zero)
                    return false;
            }

            return (thisVal.RabinMillerTest(confidence));
        }

        public static bool IsSafePrime(this BigInteger thisVal, int confidence)
        {
            if (!thisVal.IsProbablePrime(confidence))
                return false;
            // thisVal(q) is safe prime if in q =(2p - 1), p is also a probable prime
            // p =(q - 1) / 2
            var test = thisVal.Subtract(1).Divide(2);
            return test.IsProbablePrime(confidence);
        }

        public static BigInteger GeneratePseudoPrime(int bits, int confidence, Random rand)
        {
            while (true)
            {
                BigInteger result = CreateBigInteger(bits, rand);
                if (BigInteger.Remainder(result, Two) == BigInteger.Zero)
                    result++;
                // prime test
                if (result.IsProbablePrime(confidence))
                    return result;
            }
        }

        public static BigInteger GenerateSafePrime(int bits, int confidence, Random rand)
        {
            BigInteger pseudoPrime = GeneratePseudoPrime(bits, confidence, rand);
            bool found = false;

            while (!found)
            {
                found = pseudoPrime.IsSafePrime(confidence);
                if (!found)
                    pseudoPrime = GeneratePseudoPrime(bits, confidence, rand);
            }
            return pseudoPrime;
        }
        #endregion

        #region Helper Methods
        /// <summary>
        /// Produces a hex string representation the unsigned value of this BigInteger
        /// </summary>
        public static string ToHexString(this BigInteger bigInt)
        {
            return bigInt.ToUnsignedByteArray().ToHexString();
        }

        /// <summary>
        /// Returns a byte array for what the unsigned value of bigInt would be.
        /// </summary>
        public static byte[] ToUnsignedByteArray(this BigInteger bigInt)
        {
            byte[] bigIntByteArray = bigInt.ToByteArray();
            if (bigIntByteArray[bigIntByteArray.Length - 1] == 0)
            {
                var shortenedByteArray = new byte[bigIntByteArray.Length - 1];
                for (int i = 0; i < shortenedByteArray.Length; i++)
                {
                    shortenedByteArray[i] = bigIntByteArray[i];
                }
                bigIntByteArray = shortenedByteArray;
            }
            return bigIntByteArray;
        }

        /// <summary>
        /// Makes a BigInteger the value it would be if the BigInteger class was unsigned.
        /// </summary>
        private static BigInteger MakePositive(this BigInteger inValue)
        {
            if (inValue < 0)
            {
                byte[] oldBytes = inValue.ToByteArray();
                var newBytes = new byte[oldBytes.Length + 1];
                for (int i = 0; i < oldBytes.Length; i++)
                    newBytes[i] = oldBytes[i];
                newBytes[oldBytes.Length] = 0;
                return new BigInteger(newBytes);
            }
            return inValue;
        }

        private static byte GetHexadecimalByte(char c1, char c2)
        {
            byte upperByte = HexadecimalCharToByte(c1);
            byte lowByte = HexadecimalCharToByte(c2);
            upperByte = (byte)(upperByte << 4);
            return (byte)(upperByte | lowByte);
        }

        /// <summary>
        /// Returns the hexadecimal byte value that the specified character represents.
        /// </summary>
        private static byte HexadecimalCharToByte(char c)
        {
            switch (c)
            {
                case '0': return 0;     case '1': return 1;
                case '2': return 2;     case '3': return 3;
                case '4': return 4;     case '5': return 5;
                case '6': return 6;     case '7': return 7;
                case '8': return 8;     case '9': return 9;
                case 'a': return 10;    case 'A': return 10;
                case 'b': return 11;    case 'B': return 11;
                case 'c': return 12;    case 'C': return 12;    
                case 'd': return 13;    case 'D': return 13;
                case 'e': return 14;    case 'E': return 14;
                case 'f': return 15;    case 'F': return 15;
            }
            throw new FormatException("Invalid hexadecimal character");
        }
        #endregion
    }
}
BUT it will not work and you'd have to figure out how TQ altered the algorithm etc.

Hint: Reverse engineer the client to see if you can find matching patterns of the algorithm.
Super Aids is offline  
Thanks
1 User
Old 06/22/2018, 08:22   #8
 
elite*gold: 0
Join Date: Mar 2014
Posts: 16
Received Thanks: 4
Quote:
Originally Posted by Spirited View Post
I was trying to save you some time by not telling you, but it you're so insistent on trying to reverse it, or much more likely pay someone to reverse it, then good luck. It's a custom, off-spec SRP6 implementation. It's changed twice now. Enjoy.

Quote:
Originally Posted by Super Aids View Post
A good place to start would be this:

Code:
using System;
using System.Numerics;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace SRP6
{
    public class Srp6
    {
        #region Modulus(N), salt, generator(g), multiplier(k), Identity Hash
        public BigInteger Modulus
        {
            get;
            private set;
        }

        public BigInteger Salt
        {
            get;
            private set;
        }

        public BigInteger Generator
        {
            get;
            private set;
        }

        public BigInteger Multiplier
        {
            get;
            private set;
        }

        public byte[] IdentityHash
        {
            get;
            private set;
        }
        #endregion

        #region Server calculated properties
        public BigInteger SaltedIdentityHash
        {
            get;
            private set;
        }

        public BigInteger Scrambler
        {
            get;
            private set;
        }

        public BigInteger Verifier
        {
            get;
            private set;
        }
        #endregion

        #region Common properties
        public BigInteger SessionKey
        {
            get;
            private set;
        }

        public BigInteger PrivateKey
        {
            get;
            private set;
        }

        public BigInteger PublicKey
        {
            get;
            private set;
        }

        public bool IsServerInstance
        {
            get;
            private set;
        }
        #endregion

        #region Encryption/Decryption properties
        /// <summary>
        /// The initial vector used for the AES Decrypt/Encrypt methods
        /// </summary>
        public string InitialVector
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the hash algorithm.
        /// </summary>
        public string HashAlgorithm
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the password iterations.
        /// </summary>
        public int PasswordIterations
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the size of the key.
        /// </summary>
        public int KeySize
        {
            get;
            private set;
        }
        #endregion

        #region Constructors
        private Srp6(string initialVector, string modulus, int generator, byte[] identityHash)
        {
            HashAlgorithm = "SHA1";
            PasswordIterations = 2;
            KeySize = 256;
            InitialVector = initialVector;

            IdentityHash = identityHash;
            Modulus = BigIntegerExtensions.CreateBigInteger(modulus, 16);
            Generator = BigIntegerExtensions.CreateBigInteger("" + generator, 10);
            Multiplier = BigIntegerExtensions.CreateBigInteger("3", 10);
        }

        // Server Constructor, Radix 16 strings, 256-bit predef values
        public Srp6(byte[] identityHash, string modulus, int generator, int saltBits,
            int scramblerBits, string initialVector = "OFRna73m*aze01xY")
            : this(initialVector, modulus, generator, identityHash)
        {
            // This SRP6 instance is a server instance
            IsServerInstance = true;

            // Generate the Salt
            Salt = BigIntegerExtensions.CreateBigInteger(saltBits, new Random());

            // Set the salted identity hash, scrambler, and verifier
            Scrambler = BigIntegerExtensions.CreateBigInteger(scramblerBits, new Random());
            SaltedIdentityHash = Salt.CreateSaltedIdentityHash(identityHash);
            Verifier = Generator.ModPow(SaltedIdentityHash, Modulus);

            // Random 128 bit number that is a probable prime
            PrivateKey = BigIntegerExtensions.GeneratePseudoPrime(128, 100, new Random());

            // kv + g^b  (mod N)
            PublicKey = Multiplier.Multiply(Verifier).Add(Generator.ModPow(PrivateKey, Modulus));
        }

        // Client Constructor, salt not generated by client
        public Srp6(byte[] identityHash, String modulus, int generator,
            String salt, string initialVector = "OFRna73m*aze01xY")
            : this(initialVector, modulus, generator, identityHash)
        {
            // This SRP6 instance is a client instance
            IsServerInstance = false;

            // Convert the salt string to a BigInteger
            Salt = BigIntegerExtensions.CreateBigInteger(salt, 16);

            // Set the salted identity hash
            SaltedIdentityHash = Salt.CreateSaltedIdentityHash(identityHash);                

            // Generate a pseudo prime to use for the private key
            PrivateKey = BigIntegerExtensions.GeneratePseudoPrime(128, 100, new Random());

            // g^a (mod N)
            PublicKey = Generator.ModPow(PrivateKey, Modulus);
        }
        #endregion

        #region Set Session Key
        public void SetSessionKey(String pubKeyString, String scrambler = null)
        {
            BigInteger pubKey = BigIntegerExtensions.CreateBigInteger(pubKeyString, 16);
            if (IsServerInstance)       // Server SessionKey
            {
                // (Av^u) ^ b (mod N)
                SessionKey = pubKey.Multiply(Verifier.ModPow(Scrambler, Modulus)).ModPow(PrivateKey, Modulus);
            }
            else                        // Client SessionKey
            {
                Scrambler = BigIntegerExtensions.CreateBigInteger(scrambler, 16);
                BigInteger temp = PrivateKey.Add(Scrambler.Multiply(SaltedIdentityHash));
                SessionKey = pubKey.Subtract((Generator.ModPow(SaltedIdentityHash, Modulus))
                                             .Multiply(Multiplier)).ModPow(temp, Modulus);
            }
        }
        #endregion

        #region Encryption methods
        /// <summary>
        /// Encrypts a string
        /// </summary>
        /// <param name="plainText">Text to be encrypted</param>
        /// <returns>The encrypted string</returns>
        public string Encrypt(string plainText)
        {
            if(string.IsNullOrEmpty(plainText))
                return "";
            var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            var cipherTextBytes = Encrypt(plainTextBytes);
            return Convert.ToBase64String(cipherTextBytes);
        }

        /// <summary>
        /// Encrypt the specified stream. This should be called in a using statement.
        /// </summary>
        /// <param name='stream'>Stream to encrypt</param>
        /// <returns>An encrypted memory stream</returns>
        public Stream Encrypt(Stream stream)
        {
            var results = new byte[stream.Length];
            stream.Read(results, 0, results.Length);
            byte[] encryptedBytes = Encrypt(results);
            return new MemoryStream(encryptedBytes, false);
        }

        /// <summary>
        /// Encrypt the specified plainTextBytes
        /// </summary>
        /// <param name='plainTextBytes'>Plain text bytes</param>
        /// <returns>Encrypted text bytes</returns>
        public byte[] Encrypt(byte[] plainTextBytes)
        {
            string password = SessionKey.ToHexString();
            string salt = Salt.ToHexString();
            if(plainTextBytes == null)
                return null;
            byte[] initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
            var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, HashAlgorithm, PasswordIterations);
            byte[] keyBytes = derivedPassword.GetBytes(KeySize / 8);
            var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
            byte[] cipherTextBytes;
            using(var encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes))
            {
                using(var memStream = new MemoryStream())
                {
                    using(var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                        cryptoStream.FlushFinalBlock();
                        cipherTextBytes = memStream.ToArray();
                        memStream.Close();
                        cryptoStream.Close();
                    }
                }
            }
            symmetricKey.Clear();
            return cipherTextBytes;
        }
        #endregion

        #region Decryption methods
        /// <summary>
        /// Decrypts a string
        /// </summary>
        /// <param name="cipherText">Text to be decrypted</param>
        /// <returns>The decrypted string</returns>
        public string Decrypt(string cipherText)
        {
            if(string.IsNullOrEmpty(cipherText))
                return "";
            int byteCount;
            byte[] plainTextBytes = Decrypt(Convert.FromBase64String(cipherText), out byteCount);
            return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
        }

        /// <summary>
        /// Decrypt the specified stream. This should be called in a using statement.
        /// </summary>
        /// <param name='stream'>Stream to decrypt</param>
        /// <returns>A decrypted memory stream</returns>
        public Stream Decrypt(Stream stream)
        {
            var results = new byte[stream.Length];
            stream.Read(results, 0, results.Length);
            byte[] decryptedBytes = Decrypt(results);
            return new MemoryStream(decryptedBytes, false);
        }

        /// <summary>
        /// Decrypt the specified cipherTextBytes.
        /// </summary>
        /// <param name='cipherTextBytes'>Cipher text bytes</param>
        /// <returns>Decrypted text bytes</returns>
        public byte[] Decrypt(byte[] cipherTextBytes)
        {
            if(cipherTextBytes == null)
                return null;
            int byteCount;
            byte[] decryptedArray = Decrypt(cipherTextBytes, out byteCount);
            return decryptedArray.SubArray(0, byteCount);
        }

        private byte[] Decrypt(byte[] cipherTextBytes, out int byteCount)
        {
            string password = SessionKey.ToHexString();
            string salt = Salt.ToHexString();
            if(cipherTextBytes == null)
            {
                byteCount = 0;
                return null;
            }
            byte[] initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
            var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, HashAlgorithm, PasswordIterations);
            var keyBytes = derivedPassword.GetBytes(KeySize / 8);
            var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
            var plainTextBytes = new byte[cipherTextBytes.Length];
            using(var decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes))
            {
                using(var memStream = new MemoryStream(cipherTextBytes))
                {
                    using(var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                    {

                        byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                        memStream.Close();
                        cryptoStream.Close();
                    }
                }
            }
            symmetricKey.Clear();
            return plainTextBytes;
        }
        #endregion
    }
}
Code:
using System;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;

namespace SRP6
{
    /// <summary>
    /// Srp6 extenstion methods
    /// </summary>
    public static class OtherExtensions
    {
        /// <summary>
        /// Create a BigInteger from a hash of the salt and identity hash (SaltedIdentityHash).
        /// </summary>
        /// <param name='salt'>The salt</param>
        /// <param name='identityHash'>The identity hash</param>
        public static BigInteger CreateSaltedIdentityHash(this BigInteger salt, byte[] identityHash)
        {
            return BigIntegerExtensions.CreateBigInteger(
                Concatenate(salt.ToByteArray(), identityHash).Sha1Hash().ToHexString(), 16);
        }

        /// <summary>
        /// This is a SHA1 hash extension method.
        /// </summary>
        /// <returns>The hash</returns>
        /// <param name='arg1'>The byte array</param>
        public static byte[] Sha1Hash(this byte[] arg1)
        {
            try
            {
                if ((arg1 == null) || (arg1.Length == 0))
                    throw new InvalidOperationException("arg1 can not be null or have a length of zero.");
                SHA1 sha = new SHA1CryptoServiceProvider();
                sha.ComputeHash(arg1);
                return sha.Hash;
            }
            catch(Exception e)
            {
                Console.WriteLine("Sha1Hash: " + e.Message);
                return null;
            }
        }

        /// <summary>
        /// Concatenates multiple byte arrays
        /// </summary>
        /// <returns>The concatenated array</returns>
        /// <param name='arrays'>The source arrays</param>
        private static byte[] Concatenate(params byte[][] arrays)
        {
            var length = arrays.Where(array => array != null).Sum(array => array.Length) + 1;
            var result = new byte[length];
            length = 0;
            foreach (var array in arrays.Where(array => array != null))
            {
                Array.Copy(array, 0, result, length, array.Length);
                length += array.Length;
            }
            return result;
        }

        /// <summary>
        /// Extracts an array from an array
        /// </summary>
        /// <returns>The new array.</returns>
        /// <param name='sourceArray'>The source array</param>
        /// <param name='offset'>The offset to start building the new array</param>
        /// <param name='length'>The length of the new array.</param>
        public static T[] SubArray<T>(this T[] sourceArray, int offset, int length)
        {
            var result = new T[length];
            Array.Copy(sourceArray, offset, result, 0, length);
            return result;
        }

        /// <summary>
        /// Converts a byte array into a hex formatted text string.
        /// </summary>
        /// <returns>Hex formatted text string</returns>
        /// <param name="byteArray">The byte array to convert</param>
        public static string ToHexString(this byte[] byteArray)
        {
            if (byteArray == null)
                return "";
            string result = "";
            for (int i = byteArray.Length - 1; i >= 0; i--)
                result += byteArray[i].ToString("X2");
            return result;
        }

        public static string ToString(this byte[] totalArray, int offset, int length)
        {
            byte[] array = SubArray(totalArray, offset, length);
            return Encoding.ASCII.GetString(array);
        }

    }
}
Code:
using System;
using System.Numerics;

namespace SRP6
{
    /// <summary>
    /// This class adds additional support for .NET BigInteger.
    /// </summary>
    public static class BigIntegerExtensions
    {
        #region Constants
        public static readonly BigInteger Two = new BigInteger(2);
        public static readonly uint[] SmallPrimes = {
            2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
            73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
            157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,
            239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
            331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
            421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
            509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607,
            613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
            709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811,
            821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
            919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,

            1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087,
            1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181,
            1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279,
            1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
            1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471,
            1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
            1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637,
            1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
            1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867,
            1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973,
            1979, 1987, 1993, 1997, 1999, 
        
            2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089,
            2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207,
            2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
            2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389,
            2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
            2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621,
            2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707,
            2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797,
            2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
            2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
            
            3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109,
            3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
            3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329,
            3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449,
            3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539,
            3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631,
            3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733,
            3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
            3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943,
            3947, 3967, 3989,
            
            4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091,
            4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
            4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289,
            4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423,
            4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523,
            4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649,
            4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759,
            4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
            4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987,
            4993, 4999,
            
            5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101,
            5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 
            5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351,
            5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449,
            5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563,
            5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669,
            5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
            5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869,
            5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987
        };
        #endregion

        #region Additional construction functions
        /// <summary>
        /// Create a BigInteger from the specified text and convertBase.
        /// </summary>
        /// <param name='text'>A text string representing the number</param>
        /// <param name='convertBase'>The convertion base</param>
        public static BigInteger CreateBigInteger(string text, int convertBase)
        {
            if (convertBase == 16)
            {
                var isEvenLength = (text.Length % 2 == 0);
                var length = (text.Length / 2) + (isEvenLength ? 0 : 1);
                var result = new byte[length + 1];
                for (var i = 0; i < length; i++)
                {
                    var j = text.Length - (i * 2) - 1;
                    var ch1 = '0';
                    if (j > 0)
                        ch1 = text[j - 1];
                    var b = GetHexadecimalByte(ch1, text[j]);
                    result[i] = b;
                }
                result[length] = 0;
                return new BigInteger(result).MakePositive();
            }
            if (convertBase == 10)
                return BigInteger.Parse(text).MakePositive();
            throw new Exception("Unsupported conversion base");
        }

        /// <summary>
        /// Create a random BigInteger with the specified number of bits.
        /// </summary>
        /// <param name='numberOfBits'>Number of bits</param>
        /// <param name='random'>The Random instance for generating the BigInteger</param>
        public static BigInteger CreateBigInteger(int numberOfBits, Random random)
        {
            var numberOfFullBytes = numberOfBits / 8;
            var numberOfRemainingBits = numberOfBits % 8;
            var numberOfBytes = numberOfFullBytes +(numberOfRemainingBits > 0 ? 1 : 0);

            // This retry loop was added to handle weird exceptions from Mono's version of the BigInteger class
            // ToDo: Verify exactly what is causing this problem
            for (var i = 0; i < 3; i++)
            {
                try
                {
                    var randomBytes = new byte[numberOfBytes];
                    random.NextBytes(randomBytes);

                    // Mask off unused bits
                    if (numberOfRemainingBits > 0)
                        randomBytes[randomBytes.Length - 1] =
                            MaskBits(randomBytes[randomBytes.Length - 1], 8 - numberOfRemainingBits);
                    
                    // Make unsigned and return result
                    return new BigInteger(randomBytes).MakePositive();
                }
                catch (Exception)
                {
                    // If it's the last retry iteration, just throw the exception
                    if (i == 2)
                        throw;
                }
            }

            // This should be unreachable code
            throw new Exception("Should not happen");
        }
        #endregion

        #region Instance extensions for BigInteger static math functions
        public static BigInteger ModPow(this BigInteger bigInt, BigInteger exponent,
            BigInteger modulus)
        {
            return BigInteger.ModPow(bigInt, exponent, modulus);
        }

        public static BigInteger Multiply(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Multiply(bigInt, value);
        }

        public static BigInteger Add(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Add(bigInt, value);
        }

        public static BigInteger Subtract(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Subtract(bigInt, value);
        }

        public static BigInteger Divide(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.Divide(bigInt, value);
        }

        public static BigInteger Gcd(this BigInteger bigInt, BigInteger value)
        {
            return BigInteger.GreatestCommonDivisor(bigInt, value);
        }
        #endregion

        #region Bit masking and BitCount
        private static byte MaskBits(byte b, int bitCount)
        {
            if (bitCount == 7)
                return (byte)(b & 1);
            if (bitCount == 6)
                return (byte)(b & 3);
            if(bitCount == 5)
                return (byte)(b & 7);
            if(bitCount == 4)
                return (byte)(b & 15);
            if(bitCount == 3)
                return (byte)(b & 31);
            if(bitCount == 2)
                return (byte)(b & 63);
            if(bitCount == 1)
                return (byte)(b & 127);
            throw new ArgumentException("bitCount is not from 1-7");
        }

        public static int BitCount(this BigInteger bigInt)
        {
            byte[] bytes = bigInt.ToUnsignedByteArray();
            return (bytes.Length * sizeof(byte));
        }
        #endregion

        #region Prime number testing
        // Modified from http://www.codeproject.com/Articles/2728/C-BigInteger-Class for use with the BigInteger
        public static bool RabinMillerTest(this BigInteger thisVal, int confidence)
        {
            byte[] bytes = thisVal.ToUnsignedByteArray();
            if (bytes.Length == 1)
            {
                // test small numbers
                if (bytes[0] == 0 || bytes[0] == 1)
                    return false;
                if (bytes[0] == 2 || bytes[0] == 3)
                    return true;
            }

            if ((bytes[0] & 0x1) == 0)     // even numbers
                return false;

            // calculate values of s and t
            BigInteger pSub1 = thisVal - (new BigInteger(1));
            byte[] pSub1Bytes = pSub1.ToUnsignedByteArray();
            int s = 0;

            for (var index = 0; index < pSub1Bytes.Length; index++)
            {
                uint mask = 0x01;

                for (var i = 0; i < 32; i++)
                {
                    if ((pSub1Bytes[index] & mask) != 0)
                    {
                        index = pSub1Bytes.Length;      // to break the outer loop
                        break;
                    }
                    mask <<= 1;
                    s++;
                }
            }

            BigInteger t = pSub1 >> s;

            int bits = thisVal.BitCount();
            BigInteger a = new BigInteger().MakePositive();
            var rand = new Random();

            for (var round = 0; round < confidence; round++)
            {
                var done = false;

                while (!done)        // generate a < n
                {
                    int testBits = 0;

                    // make sure "a" has at least 2 bits
                    while (testBits < 2)
                        testBits =(int)(rand.NextDouble() * bits);

                    a = CreateBigInteger(testBits, rand);
                    byte[] aBytes = a.ToUnsignedByteArray();

                    // make sure "a" is not 0
                    if (aBytes.Length > 1 ||(aBytes.Length == 1 && aBytes[0] != 1))
                        done = true;
                }

                // check whether a factor exists(fix for version 1.03)
                BigInteger gcdTest = a.Gcd(thisVal);
                byte[] gcdBytes = gcdTest.ToUnsignedByteArray();
                if (gcdBytes.Length == 1 && gcdBytes[0] != 1)
                    return false;

                BigInteger b = a.ModPow(t, thisVal);
                byte[] bBytes = b.ToUnsignedByteArray();

                var result = bBytes.Length == 1 && bBytes[0] == 1;

                for (var j = 0; result == false && j < s; j++)
                {
                    if (b == pSub1)         // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1
                    {
                        result = true;
                        break;
                    }

                    b =(b * b) % thisVal;
                }

                if (result == false)
                    return false;
            }
            return true;
        }

        public static bool IsProbablePrime(this BigInteger thisVal, int confidence)
        {
            // test for divisibility by the smaller primes
            for (var p = 0; p < SmallPrimes.Length; p++)
            {
                BigInteger divisor = SmallPrimes[p];

                if (divisor >= thisVal)
                    break;

                BigInteger resultNum = thisVal % divisor;
                if (resultNum == BigInteger.Zero)
                    return false;
            }

            return (thisVal.RabinMillerTest(confidence));
        }

        public static bool IsSafePrime(this BigInteger thisVal, int confidence)
        {
            if (!thisVal.IsProbablePrime(confidence))
                return false;
            // thisVal(q) is safe prime if in q =(2p - 1), p is also a probable prime
            // p =(q - 1) / 2
            var test = thisVal.Subtract(1).Divide(2);
            return test.IsProbablePrime(confidence);
        }

        public static BigInteger GeneratePseudoPrime(int bits, int confidence, Random rand)
        {
            while (true)
            {
                BigInteger result = CreateBigInteger(bits, rand);
                if (BigInteger.Remainder(result, Two) == BigInteger.Zero)
                    result++;
                // prime test
                if (result.IsProbablePrime(confidence))
                    return result;
            }
        }

        public static BigInteger GenerateSafePrime(int bits, int confidence, Random rand)
        {
            BigInteger pseudoPrime = GeneratePseudoPrime(bits, confidence, rand);
            bool found = false;

            while (!found)
            {
                found = pseudoPrime.IsSafePrime(confidence);
                if (!found)
                    pseudoPrime = GeneratePseudoPrime(bits, confidence, rand);
            }
            return pseudoPrime;
        }
        #endregion

        #region Helper Methods
        /// <summary>
        /// Produces a hex string representation the unsigned value of this BigInteger
        /// </summary>
        public static string ToHexString(this BigInteger bigInt)
        {
            return bigInt.ToUnsignedByteArray().ToHexString();
        }

        /// <summary>
        /// Returns a byte array for what the unsigned value of bigInt would be.
        /// </summary>
        public static byte[] ToUnsignedByteArray(this BigInteger bigInt)
        {
            byte[] bigIntByteArray = bigInt.ToByteArray();
            if (bigIntByteArray[bigIntByteArray.Length - 1] == 0)
            {
                var shortenedByteArray = new byte[bigIntByteArray.Length - 1];
                for (int i = 0; i < shortenedByteArray.Length; i++)
                {
                    shortenedByteArray[i] = bigIntByteArray[i];
                }
                bigIntByteArray = shortenedByteArray;
            }
            return bigIntByteArray;
        }

        /// <summary>
        /// Makes a BigInteger the value it would be if the BigInteger class was unsigned.
        /// </summary>
        private static BigInteger MakePositive(this BigInteger inValue)
        {
            if (inValue < 0)
            {
                byte[] oldBytes = inValue.ToByteArray();
                var newBytes = new byte[oldBytes.Length + 1];
                for (int i = 0; i < oldBytes.Length; i++)
                    newBytes[i] = oldBytes[i];
                newBytes[oldBytes.Length] = 0;
                return new BigInteger(newBytes);
            }
            return inValue;
        }

        private static byte GetHexadecimalByte(char c1, char c2)
        {
            byte upperByte = HexadecimalCharToByte(c1);
            byte lowByte = HexadecimalCharToByte(c2);
            upperByte = (byte)(upperByte << 4);
            return (byte)(upperByte | lowByte);
        }

        /// <summary>
        /// Returns the hexadecimal byte value that the specified character represents.
        /// </summary>
        private static byte HexadecimalCharToByte(char c)
        {
            switch (c)
            {
                case '0': return 0;     case '1': return 1;
                case '2': return 2;     case '3': return 3;
                case '4': return 4;     case '5': return 5;
                case '6': return 6;     case '7': return 7;
                case '8': return 8;     case '9': return 9;
                case 'a': return 10;    case 'A': return 10;
                case 'b': return 11;    case 'B': return 11;
                case 'c': return 12;    case 'C': return 12;    
                case 'd': return 13;    case 'D': return 13;
                case 'e': return 14;    case 'E': return 14;
                case 'f': return 15;    case 'F': return 15;
            }
            throw new FormatException("Invalid hexadecimal character");
        }
        #endregion
    }
}
BUT it will not work and you'd have to figure out how TQ altered the algorithm etc.

Hint: Reverse engineer the client to see if you can find matching patterns of the algorithm.
greets ,
sorry for late
firstly thanks for your replies and trying to help <3 ,


but i think it's not a custom SRP6
cuz there is seed to create keys it's built on time and some protected methods
after analyse the packet sniff and reverse the client more times it's not a SRP6 never
it's just 2 or 3 encryption with 3 types different
i think soon i'll got it
just encourage me , and if you found anything with your test please tell me

sorry for my bad english
Ahmed El5WaGa is offline  
Old 06/22/2018, 09:38   #9
 
elite*gold: 12
Join Date: Jul 2011
Posts: 6,963
Received Thanks: 3,329
I have the feeling that there's some echo chamber going on. That someone on the Turkish/Egyptian forums mentioned the seed addition to the newest client's password cryptography without actually mentioning the word SRP6. Duplication of the request within a day of each other for the same information and given the same information is just too damning for that not to be the case. And yes, it's still SRP6, custom. Just because they added the seed doesn't mean it's suddenly not SRP6. Just because you add a propeller to a plane doesn't suddenly make it not a plane. And what do you mean "protected methods". Protection/scoping is just an access gimmick of higher languages. Nothing is "protected" in assembly. Geez, please give up. You're not going to magically crack this with no experience.... there's no way in hell I'd encourage you to waste time like this.
Spirited is offline  
Old 06/23/2018, 17:02   #10
 
elite*gold: 0
Join Date: Dec 2012
Posts: 1,593
Received Thanks: 825
Quote:
Originally Posted by Spirited View Post
Just because you add a propeller to a plane doesn't suddenly make it not a plane.
So this is not a helicopter?



Super Aids is offline  
Reply



« auto hunt /loot system | What is Proto With Conquer »

Similar Threads
[Release] The New Cryptography [Cast-128/Cast-5]
That's right... I decided to because everyone who shouldn't have it has already figured it out... and it's starting to spread quickly. There really...
53 Replies - CO2 PServer Guides & Releases
Password Cryptography
#Problem solved Thank You everybody, I Appreciate this.
13 Replies - CO2 PServer - Discussions / Questions
Client Server Cryptography?
i was wondering, the communication between alefcient and the game server is encrypted, and alefclient binary seems to use Cryptography API (CNG) with...
7 Replies - Archlord



All times are GMT +2. The time now is 14:42.


Powered by vBulletin®
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Abuse
Copyright ©2018 elitepvpers All Rights Reserved.