示例#1
0
        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));
        }
示例#4
0
        /// <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);
            }
        }