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