From 96f7832722bfc5bc9e5075e5a3a3599549fa81b4 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sun, 5 Jan 2020 23:04:38 +0100 Subject: [PATCH] Added password change for streams --- Encrypter Tests/EncrypterTests.cs | 87 +++++++++++++++++++++++++++++++ Encrypter/CryptoProcessor.cs | 39 ++++++++++++++ Encrypter/Encrypter.xml | 11 ++++ 3 files changed, 137 insertions(+) diff --git a/Encrypter Tests/EncrypterTests.cs b/Encrypter Tests/EncrypterTests.cs index ddad93c..d73ff9b 100644 --- a/Encrypter Tests/EncrypterTests.cs +++ b/Encrypter Tests/EncrypterTests.cs @@ -279,6 +279,93 @@ namespace Encrypter_Tests } } + [Test] + public async Task TestChangedPasswordBehaviourStreaming() + { + var tempFileInput = Path.GetTempFileName(); + var tempFileEncryptedPrevious = Path.GetTempFileName(); + var tempFileReEncrypted = Path.GetTempFileName(); + var tempFileDecrypted = Path.GetTempFileName(); + + try + { + var message = "This is a test with umlauts äüö."; + await File.WriteAllTextAsync(tempFileInput, message); + + var passwordPrevious = "test password"; + var passwordNext = "better password"; + var iterations = 1_000; + + await using (var outputStream = File.OpenWrite(tempFileEncryptedPrevious)) + { + await using var inputStream = File.OpenRead(tempFileInput); + await CryptoProcessor.Encrypt(inputStream, outputStream, passwordPrevious, iterations); + } + + await using (var outputStream = File.OpenWrite(tempFileReEncrypted)) + { + await using var inputStream = File.OpenRead(tempFileEncryptedPrevious); + await CryptoProcessor.ChangePassword(inputStream, outputStream, passwordPrevious, passwordNext, iterations); + } + + Assert.That(await File.ReadAllBytesAsync(tempFileEncryptedPrevious), Is.Not.EqualTo(await File.ReadAllBytesAsync(tempFileReEncrypted))); + + await using (var outputStream = File.OpenWrite(tempFileDecrypted)) + { + await using var inputStream = File.OpenRead(tempFileReEncrypted); + await CryptoProcessor.Decrypt(inputStream, outputStream, passwordNext, iterations); + } + + Assert.That(await File.ReadAllTextAsync(tempFileDecrypted), Is.EqualTo(message)); + + try + { + await using var tempBuffer = new MemoryStream(); + await using var inputStream = File.OpenRead(tempFileReEncrypted); + await CryptoProcessor.Decrypt(inputStream, tempBuffer, passwordPrevious, iterations); + Assert.Fail("Should not be reached!"); + } + catch (CryptographicException e) + { + Assert.That(true); + } + } + finally + { + try + { + File.Delete(tempFileInput); + } + catch + { + } + + try + { + File.Delete(tempFileDecrypted); + } + catch + { + } + + try + { + File.Delete(tempFileEncryptedPrevious); + } + catch + { + } + + try + { + File.Delete(tempFileReEncrypted); + } + catch + { + } + } + } + [Test] public async Task TestSimpleStream() { diff --git a/Encrypter/CryptoProcessor.cs b/Encrypter/CryptoProcessor.cs index a9c9fb7..28c9645 100644 --- a/Encrypter/CryptoProcessor.cs +++ b/Encrypter/CryptoProcessor.cs @@ -374,5 +374,44 @@ namespace Encrypter // Encrypt the data with the new settings: return await CryptoProcessor.Encrypt(decryptedData, newPassword, iterations); } + + /// + /// Changes the password of the encryption. In order to re-encrypt the stream, a temporary file + /// gets used. When the returned task is finished, the re-encryption is done as well. + /// + /// With the previous password encrypted data. + /// The re-encrypted data. + /// The previous password. + /// The new password. + /// The used iterations. + public static async Task ChangePassword(Stream encryptedInput, Stream reEncryptedOutput, string previousPassword, string newPassword, int iterations = ITERATIONS_YEAR_2020) + { + var tempFileCache = Path.GetTempFileName(); + + try + { + await using (var tempCacheStream = File.OpenWrite(tempFileCache)) + { + // Decrypt the data with the previous settings: + await Decrypt(encryptedInput, tempCacheStream, previousPassword, iterations); + } + + await using (var tempCacheStream = File.OpenRead(tempFileCache)) + { + // Encrypt the data with the new settings: + await Encrypt(tempCacheStream, reEncryptedOutput, newPassword, iterations); + } + } + finally + { + try + { + File.Delete(tempFileCache); + } + catch + { + } + } + } } } diff --git a/Encrypter/Encrypter.xml b/Encrypter/Encrypter.xml index aaf394e..ee1f9ca 100644 --- a/Encrypter/Encrypter.xml +++ b/Encrypter/Encrypter.xml @@ -96,6 +96,17 @@ The used iterations. The re-encrypted data. + + + Changes the password of the encryption. In order to re-encrypt the stream, a temporary file + gets used. When the returned task is finished, the re-encryption is done as well. + + With the previous password encrypted data. + The re-encrypted data. + The previous password. + The new password. + The used iterations. + Encrypts this string by means of AES. The result gets base64 encoded.