diff --git a/README.md b/README.md index 3983a5d..39ca123 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![API Layer](https://img.shields.io/badge/API_Layer-121-blueviolet)](https://core.telegram.org/api/layers) [![Support Chat](https://img.shields.io/badge/Chat_with_us-on_Telegram-0088cc)](https://t.me/WTelegramClient) -# WTelegramClient +# WTelegramClient ### _Telegram client library written 100% in C# and .NET Standard_ ## How to use @@ -111,7 +111,7 @@ I've added several useful converters or implicit cast to various API object so t Beyond the TL async methods, the Client class offers a few other methods to simplify the sending of files, medias or messages. -This library works best with **.NET 5.0** and is also available for **.NET Standard 2.0** (.NET Framework 4.6.1 & .NET Core 2.0) +This library works best with **.NET 5.0+** and is also available for **.NET Standard 2.0** (.NET Framework 4.6.1+ & .NET Core 2.0+) # Development status The library is usable for most scenarios including (sequential or parallel) automated steps based on API requests/responses, or real-time monitoring of incoming Updates/messages. Secret chats have not been tested yet. diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..a4d9990 Binary files /dev/null and b/logo.png differ diff --git a/src/Encryption.cs b/src/Encryption.cs index ced363d..3ad9d4f 100644 --- a/src/Encryption.cs +++ b/src/Encryption.cs @@ -312,7 +312,8 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB Sha256.TransformFinalBlock(algo.salt2, 0, algo.salt2.Length); hash = Sha256.Hash; #if NETCOREAPP2_0_OR_GREATER - var pbkdf2 = new Rfc2898DeriveBytes(hash, algo.salt1, 100000, HashAlgorithmName.SHA512).GetBytes(64); + using var derive = new Rfc2898DeriveBytes(hash, algo.salt1, 100000, HashAlgorithmName.SHA512); + var pbkdf2 = derive.GetBytes(64); #else var pbkdf2 = PBKDF2_SHA512(hash, algo.salt1, 100000, 64); #endif @@ -360,9 +361,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB // adapted from https://github.com/dotnet/aspnetcore/blob/main/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/ManagedPbkdf2Provider.cs public static byte[] PBKDF2_SHA512(byte[] password, byte[] salt, int iterationCount, int numBytesRequested) { - // PBKDF2 is defined in NIST SP800-132, Sec. 5.3. - // http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf - + // PBKDF2 is defined in NIST SP800-132, Sec. 5.3: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf byte[] retVal = new byte[numBytesRequested]; int numBytesWritten = 0; int numBytesRemaining = numBytesRequested; @@ -371,39 +370,35 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB byte[] saltWithBlockIndex = new byte[checked(salt.Length + sizeof(uint))]; Buffer.BlockCopy(salt, 0, saltWithBlockIndex, 0, salt.Length); - using (var hashAlgorithm = new HMACSHA512(password)) + using var hashAlgorithm = new HMACSHA512(password); + for (uint blockIndex = 1; numBytesRemaining > 0; blockIndex++) { - for (uint blockIndex = 1; numBytesRemaining > 0; blockIndex++) + // write the block index out as big-endian + saltWithBlockIndex[^4] = (byte)(blockIndex >> 24); + saltWithBlockIndex[^3] = (byte)(blockIndex >> 16); + saltWithBlockIndex[^2] = (byte)(blockIndex >> 8); + saltWithBlockIndex[^1] = (byte)blockIndex; + + // U_1 = PRF(U_0) = PRF(Salt || block_index) + // T_blockIndex = U_1 + byte[] U_iter = hashAlgorithm.ComputeHash(saltWithBlockIndex); // this is U_1 + byte[] T_blockIndex = U_iter; + + for (int iter = 1; iter < iterationCount; iter++) { - // write the block index out as big-endian - saltWithBlockIndex[^4] = (byte)(blockIndex >> 24); - saltWithBlockIndex[^3] = (byte)(blockIndex >> 16); - saltWithBlockIndex[^2] = (byte)(blockIndex >> 8); - saltWithBlockIndex[^1] = (byte)blockIndex; - - // U_1 = PRF(U_0) = PRF(Salt || block_index) - // T_blockIndex = U_1 - byte[] U_iter = hashAlgorithm.ComputeHash(saltWithBlockIndex); // this is U_1 - byte[] T_blockIndex = U_iter; - - for (int iter = 1; iter < iterationCount; iter++) - { - U_iter = hashAlgorithm.ComputeHash(U_iter); - for (int j = U_iter.Length - 1; j >= 0; j--) - T_blockIndex[j] ^= U_iter[j]; - // At this point, the 'U_iter' variable actually contains U_{iter+1} (due to indexing differences). - } - - // At this point, we're done iterating on this block, so copy the transformed block into retVal. - int numBytesToCopy = Math.Min(numBytesRemaining, T_blockIndex.Length); - Buffer.BlockCopy(T_blockIndex, 0, retVal, numBytesWritten, numBytesToCopy); - numBytesWritten += numBytesToCopy; - numBytesRemaining -= numBytesToCopy; + U_iter = hashAlgorithm.ComputeHash(U_iter); + for (int j = U_iter.Length - 1; j >= 0; j--) + T_blockIndex[j] ^= U_iter[j]; + // At this point, the 'U_iter' variable actually contains U_{iter+1} (due to indexing differences). } - } - // retVal := T_1 || T_2 || ... || T_n, where T_n may be truncated to meet the desired output length - return retVal; + // At this point, we're done iterating on this block, so copy the transformed block into retVal. + int numBytesToCopy = Math.Min(numBytesRemaining, T_blockIndex.Length); + Buffer.BlockCopy(T_blockIndex, 0, retVal, numBytesWritten, numBytesToCopy); + numBytesWritten += numBytesToCopy; + numBytesRemaining -= numBytesToCopy; + } + return retVal; // retVal := T_1 || T_2 || ... || T_n, where T_n may be truncated to meet the desired output length } #endif } diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj index e72e8f7..1731208 100644 --- a/src/WTelegramClient.csproj +++ b/src/WTelegramClient.csproj @@ -14,6 +14,7 @@ Telegram client library written 100% in C# and .NET Standard Wizou Copyright © Olivier Marcoux 2021 + logo.png Telegram;Client;Api;UserBot;MTProto MIT https://github.com/wiz0u/WTelegramClient @@ -29,7 +30,11 @@ - + + + + +