Esempio n. 1
0
        public void ReceiveLoginStartInfo(String username, String password, BinaryWriter keyDataWriter)
        {
            if (state != 0)
            {
                throw new SRP6InvalidStateException();
            }

            I = Encoding.ASCII.GetBytes(username);

            sha256.Initialize();
            // this is temporary, eventually that would be saved/used differently.
            p = SRPHelpers.GetBigIntegerFromBytes(sha256.ComputeHash(Encoding.ASCII.GetBytes(username + ":" + password)));

            BigInteger x = Hash(s, p);

            v = BigInteger.ModPow(g, x, N);
            b = MakeRandomBigInteger(128);
            B = (((Hash(N, g) * v) % N) + (BigInteger.ModPow(g, b, N))) % N;
            // validated up to here.

            // TODO: Make the right checks for this.
            Byte[] s_bytes = SRPHelpers.GetBytesFromBigInteger(s);
            Byte[] B_bytes = SRPHelpers.GetBytesFromBigInteger(B);

            keyDataWriter.Write(s_bytes.Length); // 8
            keyDataWriter.Write(s_bytes, 0, s_bytes.Length);
            keyDataWriter.Write(B_bytes.Length); // 128
            keyDataWriter.Write(B_bytes, 0, B_bytes.Length);

            state = 1;
        }
Esempio n. 2
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. 3
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);
        }
Esempio n. 4
0
        public BigInteger Hash(BigInteger integer)
        {
            sha256.Initialize();

            Byte[] bytes = SRPHelpers.GetBytesFromBigInteger(integer);

            int padding = (4 - bytes.Length % 4) % 4;

            // if there's no need for padding just return a simple hash.
            if (padding == 0)
            {
                return(SRPHelpers.GetBigIntegerFromBytes(sha256.ComputeHash(bytes)));
            }

            sha256.TransformBlock(bytes, 0, bytes.Length, null, 0);
            sha256.TransformFinalBlock(s_bytesPadding[padding], 0, padding);

            // this doesnt seem to be inverted.
            return(SRPHelpers.GetBigIntegerFromBytes(sha256.Hash));
        }
Esempio n. 5
0
        // TODO: Optimize this method
        private BigInteger HashKey(BigInteger key)
        {
            sha256.Initialize();
            Byte[] output   = new Byte[64];
            Byte[] keyBytes = SRPHelpers.GetBytesFromBigInteger(key);
            Byte[] v13;
            Byte[] hash = new Byte[32];

            Int32 keyLen = keyBytes.Length;
            Int32 len0   = keyLen;
            Int32 len;

            Int32 ptr0 = 0;

            if (keyLen > 4)
            {
                do
                {
                    if (keyBytes[ptr0] == 0)
                    {
                        break;
                    }

                    len0--;
                    ptr0++;
                }while (len0 > 4);
            }

            len = len0 >> 1;
            Int32 v6 = 0;

            v13 = new Byte[len];

            if (len >> 1 != 0)
            {
                int v7 = len0 + ptr0 - 1;
                do
                {
                    v13[v6++] = keyBytes[v7];
                    v7       -= 2;
                }while (v6 < len);
            }

            hash = sha256.ComputeHash(v13);

            // copy hash to output
            for (int i = 0; i < 32; i++)
            {
                output[i * 2] = hash[i];
            }


            // make second part
            Int32 v9 = 0;


            if (len != 0)
            {
                Int32 v10 = len0 + ptr0 - 2;
                do
                {
                    v13[v9++] = keyBytes[v10];
                    v10      -= 2;
                }while (v9 < len);
            }

            hash = sha256.ComputeHash(v13);

            // copy hash to output
            for (int i = 0; i < 32; i++)
            {
                output[i * 2 + 1] = hash[i];
            }

            return(SRPHelpers.GetBigIntegerFromBytes(output));
        }
Esempio n. 6
0
 private BigInteger MakeRandomBigInteger(Int32 bytes)
 {
     Byte[] r = new Byte[bytes];
     rng.GetBytes(r);
     return(SRPHelpers.GetBigIntegerFromBytes(r) % N);
 }