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);
        }
Example #2
0
        private static TLConfigSimple DecryptSimpleConfig(string dataString)
        {
            TLConfigSimple result = null;

            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 rsa =
                "-----BEGIN RSA PUBLIC KEY-----\n" +
                "MIIBCgKCAQEAyr+18Rex2ohtVy8sroGPBwXD3DOoKCSpjDqYoXgCqB7ioln4eDCF\n" +
                "fOBUlfXUEvM/fnKCpF46VkAftlb4VuPDeQSS/ZxZYEGqHaywlroVnXHIjgqoxiAd\n" +
                "192xRGreuXIaUKmkwlM9JID9WS2jUsTpzQ91L8MEPLJ/4zrBwZua8W5fECwCCh2c\n" +
                "9G5IzzBm+otMS/YKwmR1olzRCyEkyAEjXWqBI9Ftv5eG8m0VkBzOG655WIYdyV0H\n" +
                "fDK/NWcvGqa0w/nriMD6mDjKOryamw0OP9QuYgMN0C9xMW9y8SmP4h92OAWodTYg\n" +
                "Y1hZCxdv6cs5UnW9+PWvS+WIbkh+GaWYxwIDAQAB\n" +
                "-----END RSA PUBLIC KEY-----";

            var text      = new StringReader(rsa);
            var reader    = new PemReader(text);
            var parameter = reader.ReadObject() as RsaKeyParameters;

            var modulus  = parameter.Modulus.ToByteArray();
            var exponent = parameter.Exponent.ToByteArray();

            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);
                }
            }

            using (var from = TLObjectSerializer.CreateReader(decryptedData.AsBuffer()))
            {
                var length = from.ReadInt32();
                if (length <= 0 || length > 208 || length % 4 != 0)
                {
                    Log(string.Format("Bad length {0}", length));
                    return(null);
                }

                try
                {
                    result = TLFactory.Read <TLConfigSimple>(from);
                }
                catch (Exception ex)
                {
                    Log("Could not read configSimple");
                    return(null);
                }

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

            return(result);
        }