Esempio n. 1
0
        // return big-endian authKey
        public static byte[] GetAuthKey(byte[] bBytes, byte[] g_aData, byte[] dhPrimeData)
        {
            int position = 0;
            var b        = new BigInteger(bBytes.Reverse().Concat(new byte[] { 0x00 }).ToArray());
            var dhPrime  = TLObject.GetObject <TLString>(dhPrimeData, ref position).ToBigInteger();

            position = 0;
            var g_a = TLObject.GetObject <TLString>(g_aData, ref position).ToBigInteger();

            var authKey = BigInteger.ModPow(g_a, b, dhPrime).ToByteArray(); // little endian + (may be) zero last byte

            //remove last zero byte
            if (authKey[authKey.Length - 1] == 0x00)
            {
                authKey = authKey.SubArray(0, authKey.Length - 1);
            }

            authKey = authKey.Reverse().ToArray();

            if (authKey.Length > 256)
            {
#if DEBUG
                var authKeyInfo = new StringBuilder();
                authKeyInfo.AppendLine("auth_key length > 256: " + authKey.Length);
                authKeyInfo.AppendLine("g_a=" + g_a);
                authKeyInfo.AppendLine("b=" + b);
                authKeyInfo.AppendLine("dhPrime=" + dhPrime);
                Execute.ShowDebugMessage(authKeyInfo.ToString());
#endif

                var correctedAuth = new byte[256];
                Array.Copy(authKey, authKey.Length - 256, correctedAuth, 0, 256);
                authKey = correctedAuth;
            }
            else if (authKey.Length < 256)
            {
#if DEBUG
                var authKeyInfo = new StringBuilder();
                authKeyInfo.AppendLine("auth_key length < 256: " + authKey.Length);
                authKeyInfo.AppendLine("g_a=" + g_a);
                authKeyInfo.AppendLine("b=" + b);
                authKeyInfo.AppendLine("dhPrime=" + dhPrime);
                Execute.ShowDebugMessage(authKeyInfo.ToString());
#endif

                var correctedAuth = new byte[256];
                Array.Copy(authKey, 0, correctedAuth, 256 - authKey.Length, authKey.Length);
                for (var i = 0; i < 256 - authKey.Length; i++)
                {
                    authKey[i] = 0;
                }
                authKey = correctedAuth;
            }

            return(authKey);
        }
Esempio n. 2
0
        private void SetMinMessageId(byte[] bytes)
        {
            try
            {
                var position         = 0;
                var encryptedMessage = (TLEncryptedTransportMessage) new TLEncryptedTransportMessage().FromBytes(bytes, ref position);
                encryptedMessage.Decrypt(AuthKey);

                position = 0;
                TLTransportMessage transportMessage;
                transportMessage = TLObject.GetObject <TLTransportMessage>(encryptedMessage.Data, ref position);

                MinMessageId = transportMessage.MessageId.Value;
                System.Diagnostics.Debug.WriteLine("TCPTransport set min message_id={0} seq_no={1}", transportMessage.MessageId, transportMessage.SeqNo);
            }
            catch (Exception ex)
            {
                Execute.ShowDebugMessage("SetMessageId exception " + ex);
            }
        }
        private static TLConfigSimple DecryptSimpleConfig(string dataString)
        {
            TLConfigSimple result = null;

#if !WIN_RT
            var base64Chars = dataString.Where(ch =>
            {
                var isGoodBase64 =
                    (ch == '+') || (ch == '=') || (ch == '/') ||
                    (ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9');

                return(isGoodBase64);
            }).ToArray();

            var       cleanDataString = new string(base64Chars);
            const int kGoodSizeBase64 = 344;
            if (cleanDataString.Length != kGoodSizeBase64)
            {
                Log(string.Format("Bad base64 size {0} required {1}", cleanDataString.Length, kGoodSizeBase64));
                return(null);
            }
            byte[] data = null;
            try
            {
                data = Convert.FromBase64String(cleanDataString);
            }
            catch (Exception ex)
            {
                Log("Bad base64 bytes");

                return(null);
            }
            const int kGoodSizeData = 256;
            if (data.Length != kGoodSizeData)
            {
                Log(string.Format("Bad data size {0} required {1}", data.Length, kGoodSizeData));

                return(null);
            }

            var xml = "<RSAKeyValue><Modulus>yr+18Rex2ohtVy8sroGPBwXD3DOoKCSpjDqYoXgCqB7ioln4eDCFfOBUlfXUEvM/fnKCpF46VkAftlb4VuPDeQSS/ZxZYEGqHaywlroVnXHIjgqoxiAd192xRGreuXIaUKmkwlM9JID9WS2jUsTpzQ91L8MEPLJ/4zrBwZua8W5fECwCCh2c9G5IzzBm+otMS/YKwmR1olzRCyEkyAEjXWqBI9Ftv5eG8m0VkBzOG655WIYdyV0HfDK/NWcvGqa0w/nriMD6mDjKOryamw0OP9QuYgMN0C9xMW9y8SmP4h92OAWodTYgY1hZCxdv6cs5UnW9+PWvS+WIbkh+GaWYxw==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

            var provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xml);
            var parameters = provider.ExportParameters(false);
            var modulus    = parameters.Modulus;
            var exponent   = parameters.Exponent;

            var dataBI     = new BigInteger(data.Reverse().Concat(new byte[] { 0x00 }).ToArray());
            var exponentBI = new BigInteger(exponent.Reverse().Concat(new byte[] { 0x00 }).ToArray());
            var modulusBI  = new BigInteger(modulus.Reverse().Concat(new byte[] { 0x00 }).ToArray());

            var authKey = BigInteger.ModPow(dataBI, exponentBI, modulusBI).ToByteArray();
            if (authKey[authKey.Length - 1] == 0x00)
            {
                authKey = authKey.SubArray(0, authKey.Length - 1);
            }

            authKey = authKey.Reverse().ToArray();
            if (authKey.Length > 256)
            {
                var correctedAuth = new byte[256];
                Array.Copy(authKey, authKey.Length - 256, correctedAuth, 0, 256);
                authKey = correctedAuth;
            }
            else if (authKey.Length < 256)
            {
                var correctedAuth = new byte[256];
                Array.Copy(authKey, 0, correctedAuth, 256 - authKey.Length, authKey.Length);
                for (var i = 0; i < 256 - authKey.Length; i++)
                {
                    authKey[i] = 0;
                }
                authKey = correctedAuth;
            }

            var key           = authKey.SubArray(0, 32);
            var iv            = authKey.SubArray(16, 16);
            var encryptedData = authKey.SubArray(32, authKey.Length - 32);

            var cipher = CipherUtilities.GetCipher("AES/CBC/NOPADDING");
            var param  = new KeyParameter(key);
            cipher.Init(false, new ParametersWithIV(param, iv));
            var decryptedData = cipher.DoFinal(encryptedData);

            const int kDigestSize = 16;
            var       hash        = Utils.ComputeSHA256(decryptedData.SubArray(0, 208));
            for (var i = 0; i < kDigestSize; i++)
            {
                if (hash[i] != decryptedData[208 + i])
                {
                    Log("Bad digest");
                    return(null);
                }
            }

            var position = 4;
            var length   = BitConverter.ToInt32(decryptedData, 0);
            if (length <= 0 || length > 208 || length % 4 != 0)
            {
                Log(string.Format("Bad length {0}", length));
                return(null);
            }
            try
            {
                result = TLObject.GetObject <TLConfigSimple>(decryptedData, ref position);
            }
            catch (Exception ex)
            {
                Log("Could not read configSimple");
                return(null);
            }

            if (position != length)
            {
                Log(string.Format("Bad read length {0} shoud be {1}", position, length));
                return(null);
            }
#endif

            return(result);
        }