/// <summary> /// Обработка входного pq вектора /// </summary> /// <param name="result">req_DH_params</param> /// <returns></returns> private Combinator ProcessPqAnswer(Combinator result) { // Разложение PQ на сомножители var u = result.Get <byte[]>("pq"); var bu = new BigInteger(u); // Входные строки в BE BigInteger p = RhoPollard(bu); BigInteger q = bu / p; if (p > q) { BigInteger max = q; q = p; p = max; } // Генерация encrypted data // Сформируем запрос p_q_inner_data#83c95aec pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data var nonce = result.Get <BigInteger>("nonce"); var serverNonce = result.Get <BigInteger>("server_nonce"); _newNonce = BigInteger.GenerateRandom(256); byte[] beP = p.GetBytes(); // p в BE byte[] beQ = q.GetBytes(); // q в BE var pQInnerData = new Combinator("p_q_inner_data", u, beP, beQ, nonce, serverNonce, _newNonce); if (_nonce != nonce) { throw new ArgumentException("nonce ответа несовпадает"); } SHA1 sha = SHA1.Create(); byte[] data = pQInnerData.Serialize(); byte[] hash = sha.ComputeHash(data); byte[] dataWithHash; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { bw.Write(hash); bw.Write(data); bw.Write(GenerateRandomBytes(255 - bw.BaseStream.Position)); dataWithHash = ms.ToArray(); } byte[] encryptedData = RSAEncrypt(dataWithHash); var fingerprint = result.Get <Combinator>("server_public_key_fingerprints").Get <long>(0); // HACK: отпечаток ключа return(new Combinator("req_DH_params", nonce, serverNonce, beP, beQ, fingerprint, encryptedData)); }
/// <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); }
/// <summary> /// Обработка входного pq вектора /// </summary> /// <param name="result">req_DH_params</param> /// <returns></returns> private Combinator ProcessPqAnswer(Combinator result) { // Разложение PQ на сомножители var u = result.Get<byte[]>("pq"); var bu = new BigInteger(u); // Входные строки в BE BigInteger p = RhoPollard(bu); BigInteger q = bu / p; if (p > q) { BigInteger max = q; q = p; p = max; } // Генерация encrypted data // Сформируем запрос p_q_inner_data#83c95aec pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data var nonce = result.Get<BigInteger>("nonce"); var serverNonce = result.Get<BigInteger>("server_nonce"); _newNonce = BigInteger.GenerateRandom(256); byte[] beP = p.GetBytes(); // p в BE byte[] beQ = q.GetBytes(); // q в BE var pQInnerData = new Combinator("p_q_inner_data", u, beP, beQ, nonce, serverNonce, _newNonce); if (_nonce != nonce) throw new ArgumentException("nonce ответа несовпадает"); SHA1 sha = SHA1.Create(); byte[] data = pQInnerData.Serialize(); byte[] hash = sha.ComputeHash(data); byte[] dataWithHash; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { bw.Write(hash); bw.Write(data); bw.Write(GenerateRandomBytes(255 - bw.BaseStream.Position)); dataWithHash = ms.ToArray(); } byte[] encryptedData = RSAEncrypt(dataWithHash); var fingerprint = result.Get<Combinator>("server_public_key_fingerprints").Get<long>(0); // HACK: отпечаток ключа return new Combinator("req_DH_params", nonce, serverNonce, beP, beQ, fingerprint, encryptedData); }
/// <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; }