/// <summary> /// Формирование соли по схеме substr(new_nonce, 0, 8) XOR substr(server_nonce, 0, 8) /// </summary> /// <param name="newNonce"></param> /// <param name="serverNonce"></param> /// <returns></returns> private long CalculateInitialSalt(BigInteger newNonce, BigInteger serverNonce) { var nn = new byte[8]; var sn = new byte[8]; Array.Copy(newNonce.GetBytes(), nn, 8); Array.Copy(serverNonce.GetBytes(), sn, 8); return(BitConverter.ToInt32(Aes256IgeManaged.XOR(nn, sn), 0)); }
public byte[] Serialize() { using (var ms = new MemoryStream()) { using (var bw = new BinaryWriter(ms)) { bw.Write(AuthKeyId); bw.Write(MsgKey.GetBytes()); byte[] aesKey = CalculateAesKey(0, MsgKey.GetBytes()); byte[] aesIV = CalculateIV(0, MsgKey.GetBytes()); var aesIge = new Aes256IgeManaged(aesKey, aesIV); bw.Write(aesIge.Encrypt(Data.Serialize())); } return(ms.ToArray()); } }
/// <summary> /// Генерация клиентского запроса с параметрами Диффи-Хеллмана /// </summary> /// <param name="serverDh"></param> /// <returns></returns> private Combinator SetClientDhParams(Combinator serverDh) { var g = serverDh.Get <int>("g"); var dhPrime = serverDh.Get <byte[]>("dh_prime"); var gA = serverDh.Get <byte[]>("g_a"); var dh = new DiffieHellmanManaged(dhPrime, new BigInteger(g).GetBytes(), 2048); // generate the public key of the second DH instance byte[] gB = dh.CreateKeyExchange(); // let the second DH instance compute the shared secret using the first DH public key _authKey = dh.DecryptKeyExchange(gA); // Сформируем ответ // отдаем g_b в BE var clientDhInnerData = new Combinator("client_DH_inner_data", _nonce, _serverNonce, (long)0, gB); byte[] s = clientDhInnerData.Serialize(); // Шифрование строки var aes = new Aes256IgeManaged(CalculateTmpAesKey(_newNonce, _serverNonce) , CalculateTmpAesIV(_newNonce, _serverNonce)); using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { SHA1 sha1 = SHA1.Create(); bw.Write(sha1.ComputeHash(s)); bw.Write(s); var r = new Random(); while (bw.BaseStream.Length % 16 != 0) { bw.Write((byte)r.Next()); } s = aes.Encrypt(ms.ToArray()); } // Сформируем ответ var setClientDhParams = new Combinator("set_client_DH_params", _nonce, _serverNonce, s); return(setClientDhParams); }
public EncryptedMessage(byte[] authKey, byte[] plainData) { _authKey = authKey; using (var ms = new MemoryStream(plainData)) { using (var br = new BinaryReader(ms)) { AuthKeyId = br.ReadInt64(); MsgKey = new BigInteger(br.ReadBytes(16)); // дешифруем эту дату byte[] aesKey = CalculateAesKey(8, MsgKey.GetBytes()); byte[] aesIv = CalculateIV(8, MsgKey.GetBytes()); var aesIge = new Aes256IgeManaged(aesKey, aesIv); Data = new EncryptedData(aesIge.Decrypt(br.ReadBytes(plainData.Length - 8 - 16))); } } }
/// <summary> /// Обработка DH параметров /// </summary> /// <param name="dhparams"></param> /// <returns></returns> private Combinator ProcessDhParams(Combinator dhparams) { var ea = dhparams.Get <byte[]>("encrypted_answer"); // Обновим server nonce _serverNonce = dhparams.Get <BigInteger>("server_nonce"); // Расшифровка строки var aes = new Aes256IgeManaged(CalculateTmpAesKey(_newNonce, _serverNonce), CalculateTmpAesIV(_newNonce, _serverNonce)); byte[] answerWithHash = aes.Decrypt(ea); if (answerWithHash.Length % 16 != 0) { throw new ArgumentException("Неверный ответ внутри сообщения"); } byte[] answer = answerWithHash.Skip(20).ToArray(); return(new Combinator(answer, "Server_DH_inner_data")); }