Пример #1
0
        public override bool onHandshake()
        {
            //wait for RSA from server
            RSAEncryption RSA           = null;
            SyncObject    syncObject    = null;
            DiffieHellman diffieHellman = new DiffieHellman(256);

            if (!base.ReceiveMessage((IMessage message) =>
            {
                MsgRsaPublicKey rsaKey = message as MsgRsaPublicKey;

                if (rsaKey != null)
                {
                    RSA = new RSAEncryption(Connection.RSA_KEY_SIZE, rsaKey.Modulus, rsaKey.Exponent, true);
                    return(true);
                }
                return(false);
            }).Wait <bool>(false, 30000))
            {
                if (syncObject.TimedOut)
                {
                    throw new TimeoutException(TimeOutMessage);
                }
                Client.Disconnect(DisconnectReason.TimeOut);
                throw new Exception("The RSA Exchange failed");
            }

            //Calculate and apply the public key as key
            //If the key is spoofed the next packet that's being send could fail if public key is generated wrong :)
            byte[] SecretHash = SHS_KeyExchange.CalculateSecretHash(RSA.Parameters.Modulus, RSA.Parameters.Exponent);
            Client.Connection.protection.ApplyPrivateKey(SecretHash);

            bool BlockedCertificate = false;

            if (!(syncObject = base.ReceiveMessage((IMessage message) =>
            {
                MsgServerEncryption mse = message as MsgServerEncryption;

                if (mse != null)
                {
                    Client.UseUDP = mse.UseUdp;

                    uint[] TempKey = new uint[SecretHash.Length];
                    for (int i = 0; i < TempKey.Length; i++)
                    {
                        TempKey[i] = SecretHash[i];
                    }

                    byte[] EncryptedDiffieKey = new byte[mse.Key.Length];
                    Array.Copy(mse.Key, EncryptedDiffieKey, mse.Key.Length);

                    //Decrypt the diffie-hellman key with our SecretHash which is generated by our Public RSA
                    UnsafeXor XorEncryption = new UnsafeXor(TempKey, true);
                    XorEncryption.Decrypt(mse.Key, 0, mse.Key.Length);

                    //read the Diffie-Hellman key
                    long index = Client.PrivateKeyOffset % 65535;
                    if (index <= 4)
                    {
                        index = 10;
                    }

                    byte[] diffieData = new byte[BitConverter.ToInt32(mse.Key, (int)(index - 4))]; //get the key length
                    Array.Copy(mse.Key, index, diffieData, 0, diffieData.Length);                  //copy the diffie-hellman key in between random data

                    //fix RSA Encrypted Data
                    //Array.Copy(mse.Key, mse.Key.Length - (diffieLen.Length + diffieData.Length), mse.Key, index - 4, diffieLen.Length + diffieData.Length);
                    //Array.Resize(ref mse.Key, mse.Key.Length - (diffieLen.Length + diffieData.Length)); //set original size back

                    //check if key is original
                    uint KeyHash = BitConverter.ToUInt32(new CRC32().ComputeHash(mse.Key), 0);

                    if (KeyHash != mse.KeyHash)
                    {
                        return(false);
                    }

                    diffieHellman.GenerateResponse(new PayloadReader(diffieData));
                    Client.Certificate = mse.certificate;

                    if (!Client.onVerifyCertificate(mse.certificate))
                    {
                        BlockedCertificate = true;
                        return(false);
                    }

                    Client.Connection.protection.ApplyPrivateKey(EncryptedDiffieKey); //apply Encrypted Key
                    base.SendMessage(new MsgDiffiehellman(diffieHellman.GetDiffie()));
                    Client.Connection.protection.ApplyPrivateKey(diffieHellman.Key);  //apply diffie-hellman key
                    return(true);
                }
                return(false);
            })).Wait <bool>(false, 30000))
            {
                Client.Disconnect(DisconnectReason.TimeOut);
                Client.onException(new Exception("Handshake went wrong, CHS_KeyExchange"), ErrorType.Core);
                if (!BlockedCertificate)
                {
                    if (syncObject.TimedOut)
                    {
                        throw new TimeoutException(TimeOutMessage);
                    }
                    throw new Exception("Diffie-Hellman key-exchange failed.");
                }
                throw new Exception("The certificate provided by the server was blocked by the user");
            }
            return(true);
        }
Пример #2
0
        public override bool onHandshake()
        {
            DiffieHellman diffieHellman = new DiffieHellman(256);

            //send RSA public key
            RSAEncryption RSA = KeyHandler.GetPrivateKey();

            base.SendMessage(new MsgRsaPublicKey(RSA.Parameters));

            //Calculate and apply the public key as key
            //If the key is spoofed the next packet that's being send could fail if public key is generated wrong :)
            byte[] SecretHash = SHS_KeyExchange.CalculateSecretHash(RSA.Parameters.Modulus, RSA.Parameters.Exponent);
            Client.Connection.protection.ApplyPrivateKey(SecretHash);//apply our secret hash based on the public key

            //generate a big random key
            byte[] encryptionKey = new byte[65535];
            new Random(DateTime.Now.Millisecond).NextBytes(encryptionKey);

            //encrypt the key with RSA
            byte[] cryptedKey = RSA.Encrypt(encryptionKey, 0, encryptionKey.Length);

            diffieHellman = KeyHandler.GetDiffieHellman();

            byte[] diffieStr = diffieHellman.GetDiffie();
            long   index     = Client.PrivateKeyOffset % 65535;

            if (index <= 4)
            {
                index = 10;
            }

            byte[] diffieLen = BitConverter.GetBytes(diffieStr.Length);

            //create a backup of encrypted RSA data
            //byte[] RsaBackup = new byte[diffieLen.Length + diffieStr.Length];
            //Array.Copy(cryptedKey, index - 4, RsaBackup, 0, RsaBackup.Length); //Rsa Backup Data
            Array.Copy(diffieLen, 0, cryptedKey, index - 4, diffieLen.Length); //write Diffie-Hellman key length
            Array.Copy(diffieStr, 0, cryptedKey, index, diffieStr.Length);     //copy the diffie-hellman key in between random data

            //maybe not secure adding this at the end of the encrypted data but whatever for now
            //Array.Resize(ref cryptedKey, cryptedKey.Length + RsaBackup.Length);
            //Array.Copy(RsaBackup, 0, cryptedKey, cryptedKey.Length - RsaBackup.Length, RsaBackup.Length);



            uint KeyHash = BitConverter.ToUInt32(new CRC32().ComputeHash(cryptedKey), 0);

            CertInfo certificate = new CertInfo(serverProperties.ServerCertificate);

            certificate.FingerPrintMd5  = BitConverter.ToString(MD5.Create().ComputeHash(serverProperties.ServerCertificate.PrivateKey)).Replace("-", "");
            certificate.FingerPrintSha1 = BitConverter.ToString(SHA1.Create().ComputeHash(serverProperties.ServerCertificate.PrivateKey)).Replace("-", "");
            certificate.KeyAlgorithm    = "RSA with " + Connection.RSA_KEY_SIZE + "bit";
            certificate.Compression     = ""; //serverProperties.Compression.ToString();
            certificate.Cipher          = ""; // serverProperties.Encryption.ToString();
            certificate.HandshakeMethod = "RSA" + Connection.RSA_KEY_SIZE + "-DiffieHellman-AES256";

            if (!serverProperties.ServerCertificate.ShowProtectionMethods)
            {
                certificate.Cipher          = "";
                certificate.Compression     = "";
                certificate.HandshakeMethod = "";
                certificate.KeyAlgorithm    = "";
            }

            Client.Certificate = certificate;


            //Convert bytes to UINT
            uint[] TempKey = new uint[SecretHash.Length];
            for (int i = 0; i < TempKey.Length; i++)
            {
                TempKey[i] = SecretHash[i];
            }

            //Encrypt the diffie-hellman key with our SecretHash which is generated by our Public RSA
            UnsafeXor XorEncryption = new UnsafeXor(TempKey, true);

            XorEncryption.Encrypt(ref cryptedKey, 0, cryptedKey.Length);


            //send encryption info + diffie-hellman
            base.SendMessage(new MsgServerEncryption(serverProperties.AllowUdp, certificate, cryptedKey, KeyHash));

            //apply the Encrypted Key, Yes the Encrypted Key, if spoofed the key should change at the client side ;)
            Client.Connection.protection.ApplyPrivateKey(cryptedKey);

            if (!base.ReceiveMessage((IMessage message) =>
            {
                MsgDiffiehellman diffie = message as MsgDiffiehellman;

                if (diffie != null)
                {
                    try
                    {
                        diffieHellman.HandleResponse(new PayloadReader(diffie.DiffieHellman));
                        Client.Connection.protection.ApplyPrivateKey(diffieHellman.Key); //apply diffie-hellman key
                        return(true);
                    }
                    catch { return(false); }
                }
                return(false);
            }).Wait <bool>(false, 30000))
            {
                Client.Disconnect(DisconnectReason.TimeOut);
                Client.onException(new Exception("Handshake went wrong, SHS_KeyExchange"), ErrorType.Core);
                return(false);
            }
            return(true);
        }
Пример #3
0
 public UnsafeXorProtection()
     : base()
 {
     this.unsafeXor = new UnsafeXor(true);
 }