Esempio n. 1
0
        private BigInteger Hash(params BigInteger[] integers)
        {
            if (integers == null || integers.Length <= 0)
            {
                throw new ArgumentException();
            }

            sha256.Initialize();
            Byte[] bytes;

            // iterates all but the last
            int lastIndex = integers.Length - 1;

            for (int i = 0; i < integers.Length; i++)
            {
                // padding.
                bytes = SRPHelpers.GetBytesFromBigInteger(integers[i]);
                int padding = bytes.Length % 4;

                sha256.TransformBlock(bytes, 0, bytes.Length, null, 0);
                if (padding != 0)
                {
                    sha256.TransformBlock(s_bytesPadding[4 - padding], 0, 4 - padding, null, 0);
                }
            }

            // finalize with empty block (no modification)
            sha256.TransformFinalBlock(s_bytesPadding[0], 0, 0);

            // we need to reverse the hash result as integers. I'm unsure why, I guess the game does it.
            Byte[] hash = sha256.Hash;
            SRPHelpers.ReverseBytesAsUInt32(hash);

            return(SRPHelpers.GetBigIntegerFromBytes(hash));
        }
Esempio n. 2
0
        public void ReceiveClientProof(BinaryReader clientKeyDataReader, BinaryWriter serverKeyDataWriter, out byte[] key)
        {
            if (state != 1)
            {
                throw new SRP6InvalidStateException();
            }

            // receive M_c (proof) & A (public ephemerial key)
            Int32      len = clientKeyDataReader.ReadInt32();
            BigInteger A   = SRPHelpers.GetBigIntegerFromBytes(clientKeyDataReader.ReadBytes(len));

            len = clientKeyDataReader.ReadInt32();
            Byte[] M_clientBytes = clientKeyDataReader.ReadBytes(len);

            if (A == 0) // A % N ??
            {
                throw new SRP6SafeguardException("SRP6 received invalid 'A' from server (A == 0)");
            }

            // Reverse bytes received from server.
            //SRPHelpers.ReverseBytesAsUInt32(M_clientBytes);
            BigInteger M_client = SRPHelpers.GetBigIntegerFromBytes(M_clientBytes);

            // calculate random scrambling parameter
            BigInteger u = Hash(A, B);

            // compute session key (not sure about this one, check if it's the right alg)
            S = BigInteger.ModPow((A * BigInteger.ModPow(v, u, N)) % N, b, N);
            K = HashKey(S); // I think the client uses this key to encrypt. It doesnt seem to use S at all

            // return the key
            key = SRPHelpers.GetBytesFromBigInteger(K);

            sha256.Initialize();
            Byte[]     IHash = sha256.ComputeHash(I);
            BigInteger hash  = Hash(Hash(N) ^ Hash(g),
                                    SRPHelpers.GetBigIntegerFromBytes(IHash), s, A, B, K);

            // Reverse the array.
            Byte[] bytes = SRPHelpers.GetBytesFromBigInteger(hash);
            SRPHelpers.ReverseBytesAsUInt32(bytes);
            hash = SRPHelpers.GetBigIntegerFromBytes(bytes);

            if (M_client != hash)
            {
                throw new SRP6SafeguardException("SRP6 could not validate proof 'K'.");
            }

            BigInteger M = Hash(A, M_client, K);

            Byte[] M_bytes = SRPHelpers.GetBytesFromBigInteger(M);

            //reverse byte
            SRPHelpers.ReverseBytesAsUInt32(M_bytes);

            serverKeyDataWriter.Write(M_bytes.Length); // 32
            serverKeyDataWriter.Write(M_bytes, 0, M_bytes.Length);
        }