private static async Task Main(string[] args) { Console.WriteLine("Compression Utility Nuget Library"); Console.WriteLine($"Version {typeof(ICompressionUtilityAsync).Assembly.GetName().Version} - Example CLI \n"); if (args.Length != 2) { goto error; } if (args[0] == "-c") { string compressed = await compressionUtility.Compress(args[1]); Console.WriteLine("COMPRESSED STRING: " + compressed); return; } if (args[0] == "-d") { string decompressed = await compressionUtility.Decompress(args[1]); Console.WriteLine("DECOMPRESSED STRING: " + decompressed); return; } error: Console.WriteLine("INVALID ARGS. Correct usage: \nCompressing:\t-c \"String to compress here *@% 123\" \nDecompressing:\t-d \"H4sIAAAAAAAECgtxDQ4BALiT6u4EAAAA\" \n\n"); }
#pragma warning restore 1591 /// <summary> /// Changes an Epistle <see cref="User"/>'s password. /// </summary> /// <param name="oldPw">The old <see cref="User"/> password (NOT its SHA512!).</param> /// <param name="newPw">The new, better and safer password (NOT its SHA512!).</param> /// <param name="totp">Request authentication token.</param> /// <returns>Whether the password change request was successful or not.</returns> /// <exception cref="ApplicationException">Thrown if the <see cref="User.PrivateKeyPem"/> is <c>null</c> or empty.</exception> public async Task <bool> ChangePassword(string oldPw, string newPw, string totp) { if (oldPw == newPw) { return(false); } if (user.PrivateKeyPem.NullOrEmpty()) { string msg = "The user's in-memory private key seems to be null or empty; can't change passwords without re-encrypting a new copy of the user key!"; logger?.LogError(msg); throw new ApplicationException(msg); } var dto = new UserChangePasswordRequestDto { Totp = totp, OldPwSHA512 = oldPw.SHA512(), NewPwSHA512 = newPw.SHA512(), NewPrivateKey = await keyExchange.EncryptAndCompressPrivateKeyAsync(user.PrivateKeyPem, newPw).ConfigureAwait(false) }; var requestBody = new EpistleRequestBody { UserId = user.Id, Auth = user.Token.Item2, Body = await compressionUtility.Compress(JsonSerializer.Serialize(dto)).ConfigureAwait(false) }; bool success = await userService.ChangeUserPassword(requestBody.Sign(crypto, user.PrivateKeyPem)).ConfigureAwait(false); return(success); }
/// <summary> /// Asynchronous variant of <see cref="IKeyExchange.EncryptAndCompressPrivateKey"/>. /// </summary> /// <param name="privateKeyPem">The user's private RSA key (PEM-formatted <c>string</c>).</param> /// <param name="userPassword">The user's password (NOT its SHA512!).</param> /// <returns><c>string</c> that contains the encrypted and compressed <paramref name="privateKeyPem"/>.</returns> public async Task <string> EncryptAndCompressPrivateKeyAsync(string privateKeyPem, string userPassword) { string encryptedKey = await aes.EncryptWithPasswordAsync(privateKeyPem, userPassword).ConfigureAwait(false); return(await compressionUtilityAsync.Compress(encryptedKey).ConfigureAwait(false)); }
/// <summary> /// Submits a message to a <see cref="Convo"/>. /// </summary> /// <param name="convo">The <see cref="Convo"/> to post the message into.</param> /// <param name="messageType">The type of message (e.g. "TEXT=UTF8", "FILE=example.png", etc...).</param> /// <param name="message">The message body to encrypt and post.</param> /// <returns>Whether the message could be submitted successfully or not.</returns> private async Task <bool> PostMessageToConvo(Convo convo, string messageType, byte[] message) { if (message.NullOrEmpty()) { return(false); } Task <IDictionary <string, string> > publicKeys = userService.GetUserPublicKeys(user.Id, convo.GetParticipantIdsCommaSeparated(), user.Token.Item2); byte[] compressedMessage = await compressionUtility.Compress(message, CompressionSettings.Default).ConfigureAwait(false); using var encryptionResult = await aes.EncryptAsync(compressedMessage).ConfigureAwait(false); byte[] key = new byte[48]; for (int i = 0; i < 32; i++) { key[i] = encryptionResult.Key[i]; } for (int i = 0; i < 16; i++) { key[i + 32] = encryptionResult.IV[i]; } // Encrypt the message decryption key for every convo participant individually. var encryptedKeys = new ConcurrentBag <string>(); Parallel.ForEach(await publicKeys.ConfigureAwait(false), kvp => { (string userId, string userPublicKey) = kvp; if (userId.NotNullNotEmpty() && userPublicKey.NotNullNotEmpty()) { string decompressedPublicKey = keyExchange.DecompressPublicKey(userPublicKey); encryptedKeys.Add(userId + ':' + Convert.ToBase64String(rsa.Encrypt(key, decompressedPublicKey))); } }); try { var postParamsDto = new PostMessageParamsDto { Type = messageType, SenderName = userSettings.Username, ConvoId = convo.Id, ConvoPasswordSHA512 = convoPasswordProvider.GetPasswordSHA512(convo.Id), EncryptedKeys = encryptedKeys.ToCommaSeparatedString(), EncryptedBody = Convert.ToBase64String(encryptionResult.EncryptedData) }; var body = new EpistleRequestBody { UserId = user.Id, Auth = user.Token.Item2, Body = JsonSerializer.Serialize(postParamsDto) }; return(await convoService.PostMessage(body.Sign(rsa, user.PrivateKeyPem)).ConfigureAwait(false)); } catch { return(false); } }