コード例 #1
0
        public override MazeErrorCode onReceiveData(byte[] Data, ref byte[] ResponseData)
        {
            ResponseData = new byte[0];

            if (LastErrorCode != MazeErrorCode.Success)
            {
                //don't continue if the client/server messed something up
                return LastErrorCode;
            }

            switch (base.Step)
            {
                case 1:
                {
                    //step 2
                    if (Data.Length != Mazing.ByteCode.Length)
                    {
                        SysLogger.Log("[MazeHandShake][Server] ByteCode Length Missmatch", SysLogType.Debug);
                        return MazeErrorCode.WrongByteCode;
                    }

                    for (int i = 0; i < Mazing.ByteCode.Length; i++)
                    {
                        if (Mazing.ByteCode[i] != Data[i])
                        {
                            SysLogger.Log("[MazeHandShake][Server] WrongByteCode from client", SysLogType.Debug);
                            return MazeErrorCode.WrongByteCode;
                        }
                    }
                    Step++;
                    break;
                }
                case 2:
                {
                    if (onFindKeyInDatabase == null) //programmer error
                    {
                        SysLogger.Log("[MazeHandShake][Server] onFindKeyInDatabase is null", SysLogType.Debug);
                        ResponseData = GetFailResponseData(); //not encrypted, client knows this will fail
                        return MazeErrorCode.Error;
                    }

                    string EncHashedMsg = BitConverter.ToString(SHA512Managed.Create().ComputeHash(Data, 0, Data.Length)).Replace("-", "");
                    byte[] _key = new byte[0];
                    byte[] _salt = new byte[0];
                    byte[] _publicKey = new byte[0];
                    string _userName = "";

                    if (onFindKeyInDatabase(EncHashedMsg, ref _key, ref _salt, ref _publicKey, ref _userName))
                    {
                        this.PublicKeyData = TrimArray(_publicKey, Mazing.MAX_KEY_SIZE);
                        this.wopEx = base.GetWopEncryption(_key, _salt);

                        base.FinalKey = _key;
                        base.FinalSalt = _salt;

                        //let's try to decrypt the data, should go successful
                        wopEx.Decrypt(Data, 0, Data.Length);

                        if (Data.Length != _publicKey.Length)
                        {
                            SysLogger.Log("[MazeHandShake][Server] Public key length missmatch", SysLogType.Debug);
                            //key size not the same... strange
                            ResponseData = GetFailResponseData();
                            return MazeErrorCode.Error;
                        }

                        for (int i = 0; i < _publicKey.Length; i++)
                        {
                            if (Data[i] != _publicKey[i])
                            {
                                SysLogger.Log("[MazeHandShake][Server] Public key missmatch", SysLogType.Debug);
                                //public key did not match... strange
                                ResponseData = GetFailResponseData();
                                return MazeErrorCode.Error;
                            }
                        }

                        //encryption / public key went successful for now
                        this.server_Prime = BigInteger.genPseudoPrime(256, 50, new Random(BitConverter.ToInt32(_key, 0)));
                        byte[] primeData = server_Prime.getBytes();
                        wopEx.Encrypt(primeData, 0, primeData.Length);
                        ResponseData = primeData;

                        this.Username = _userName;

                        Step++;
                    }
                    else
                    {
                        SysLogger.Log("[MazeHandShake][Server] No user key found in database", SysLogType.Debug);
                        ResponseData = GetFailResponseData();
                        return MazeErrorCode.UserKeyNotFound;
                    }
                    break;
                }
                case 3:
                {
                    //response back from client with his prime number
                    wopEx.Decrypt(Data, 0, Data.Length);

                    this.client_Prime = new BigInteger(Data);
                    if (this.client_Prime.isProbablePrime())
                    {
                        //verify the prime from the client
                        BigInteger client_Prime_test = BigInteger.genPseudoPrime(256, 50, new Random(this.server_Prime.IntValue()));

                        if (this.client_Prime != client_Prime_test)
                        {
                            //Attacker detected ?
                            SysLogger.Log("[MazeHandShake][Server] Man-In-The-Middle detected", SysLogType.Debug);
                            return MazeErrorCode.Error;
                        }

                        BigInteger key = base.ModKey(server_Prime, client_Prime);
                        //apply key to encryption
                        ApplyKey(wopEx, key);
                        return MazeErrorCode.Finished;
                    }
                    else
                    {
                        SysLogger.Log("[MazeHandShake][Server] Invalid response", SysLogType.Debug);
                        return MazeErrorCode.Error;
                    }
                }
            }
            return MazeErrorCode.Success;
        }
コード例 #2
0
 internal void ApplyKey(WopEx wopEx, BigInteger prime)
 {
     PatchKey(ref prime);
     byte[] primeKey = prime.getBytes();
     ApplyKey(wopEx, primeKey);
 }
コード例 #3
0
        /// <summary>
        /// Patches the key by removing the 255 in the beginning of the key
        /// </summary>
        /// <param name="key"></param>
        private void PatchKey(ref BigInteger key)
        {
            byte[] _key = key.getBytes();
            int count = 0;
            for (int i = 0; i < _key.Length; i++, count++)
            {
                if (_key[i] != 255)
                    break;
            }

            if (count > 0)
            {
                byte[] tempKey = new byte[count];
                new FastRandom(PrivateSalt.IntValue()).NextBytes(tempKey);
                Array.Copy(tempKey, _key, tempKey.Length);
                key = new BigInteger(_key);
            }
        }
コード例 #4
0
 public void WriteBigInteger(BigInteger BigInt)
 {
     byte[] temp = BigInt.getBytes();
     WriteByte((byte)temp.Length);
     WriteBytes(temp);
 }