public static byte[] LogonProof(IPacketReader packet) { byte[] A = packet.ReadBytes(32); byte[] kM1 = packet.ReadBytes(20); byte[] rA = A.Reverse().ToArray(); byte[] AB = A.Concat(B.GetBytes(32).Reverse()).ToArray(); if (new BigInteger(A) % new BigInteger(N) == 0) { return(new byte[1]); } using (SHA1 sha1 = new SHA1CryptoServiceProvider()) { // SS_Hash byte[] rU = sha1.ComputeHash(AB).Reverse().ToArray(); var s = V.ModPow(new BigInteger(rU), new BigInteger(RN)) * new BigInteger(rA); s = s.ModPow(new BigInteger(RB), new BigInteger(RN)); byte[] S1 = new byte[16], S2 = new byte[16]; byte[] rS = s.GetBytes(32).Reverse().ToArray(); for (int t = 0; t < 16; t++) { S1[t] = rS[t * 2]; S2[t] = rS[(t * 2) + 1]; } byte[] hashS1 = sha1.ComputeHash(S1), hashS2 = sha1.ComputeHash(S2); byte[] ss_hash = new byte[hashS1.Length + hashS2.Length]; for (int t = 0; t < hashS1.Length; t++) { ss_hash[t * 2] = hashS1[t]; ss_hash[(t * 2) + 1] = hashS2[t]; } // calc M1 & M2 byte[] NHash = sha1.ComputeHash(N); byte[] GHash = sha1.ComputeHash(G.GetBytes()); var tmp = Enumerable.Range(0, 20) .Select(t => (byte)(NHash[t] ^ GHash[t])) .Concat(sha1.ComputeHash(BUsername)) .Concat(Salt) .Concat(A) .Concat(B.GetBytes(32).Reverse()) .Concat(ss_hash); byte[] M1 = sha1.ComputeHash(tmp.ToArray()); byte[] M2 = sha1.ComputeHash(A.Concat(M1).Concat(ss_hash).ToArray()); // instantiate coders/cryptors PacketCrypt = new PacketCrypt(ss_hash, ClientBuild); // create packet data byte[] result = new byte[GetLogonProofSize()]; result[0] = 1; Array.Copy(M2, 0, result, 2, M2.Length); return(result); } }
public static byte[] LogonProof(IPacketReader packet) { byte[] A = packet.ReadBytes(32); byte[] kM1 = packet.ReadBytes(20); byte[] rA = A.Reverse().ToArray(); byte[] AB = A.Concat(B.GetBytes(32).Reverse()).ToArray(); if (new BigInteger(A) % new BigInteger(N) == 0) { return(new byte[1]); } SHA1 sha1 = new SHA1CryptoServiceProvider(); byte[] rU = sha1.ComputeHash(AB).Reverse().ToArray(); // SS_Hash BigInteger s = V.ModPow(new BigInteger(rU), new BigInteger(RN)); s *= new BigInteger(rA); s = s.ModPow(new BigInteger(RB), new BigInteger(RN)); byte[] S1 = new byte[16]; byte[] S2 = new byte[16]; byte[] S = s.GetBytes(32); byte[] rS = S.Reverse().ToArray(); for (int t = 0; t < 16; t++) { S1[t] = rS[t * 2]; S2[t] = rS[(t * 2) + 1]; } byte[] hashS1 = sha1.ComputeHash(S1); byte[] hashS2 = sha1.ComputeHash(S2); byte[] ss_hash = new byte[hashS1.Length + hashS2.Length]; for (int t = 0; t < hashS1.Length; t++) { ss_hash[t * 2] = hashS1[t]; ss_hash[(t * 2) + 1] = hashS2[t]; } // calc M1 byte[] M1; byte[] NHash = sha1.ComputeHash(N); byte[] GHash = sha1.ComputeHash(G.GetBytes()); byte[] NG_Hash = new byte[20]; for (int t = 0; t < 20; t++) { NG_Hash[t] = (byte)(NHash[t] ^ GHash[t]); } var tmp = NG_Hash.Concat(sha1.ComputeHash(BUsername)) .Concat(Salt) .Concat(A) .Concat(B.GetBytes(32).Reverse()) .Concat(ss_hash); M1 = sha1.ComputeHash(tmp.ToArray()); // calc M2 byte[] M2; tmp = A.Concat(M1).Concat(ss_hash); M2 = sha1.ComputeHash(tmp.ToArray()); sha1.Dispose(); // instantiate coders/cryptors PacketCrypt = new PacketCrypt(ss_hash, ClientBuild); // additional information, always zeroed int extradata = 0; if (ClientBuild < 6178 || ClientBuild == 6180) { extradata = 04; // uint unk } else if (ClientBuild < 8089) { extradata = 06; // uint unk, ushort unkFlags } else { extradata = 10; // uint account flag, uint surveyId, ushort unkFlags } byte[] result = new byte[22 + extradata]; result[0] = 1; Array.Copy(M2, 0, result, 2, M2.Length); return(result); }