Small refactoring and clean up
MODIFY
MagicalCryptoWallet/Crypto/StringCipher.cs
MagicalCryptoWallet/Crypto/StringCipher.cs
@@ -17,40 +17,43 @@ namespace MagicalCryptoWallet.Crypto
// This constant determines the number of iterations for the password bytes generation function.
private const int DerivationIterations = 1000;
+ private static AesManaged CreateAES()
+ {
+ var aes = new AesManaged();
+ aes.BlockSize = 128;
+ aes.Mode = CipherMode.CBC;
+ aes.Padding = PaddingMode.PKCS7;
+ return aes;
+ }
+
public static string Encrypt(string plainText, string passPhrase)
{
- // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
- // so that the same Salt and IV values can be used when decrypting.
+ // Salt is randomly generated each time, but is preprended to encrypted cipher text
+ // so that the same Salt value can be used when decrypting.
var saltStringBytes = Generate128BitsOfRandomEntropy();
- //Console.WriteLine($"saltStringBytes: {Encoders.Hex.EncodeData(saltStringBytes)}");
- //var ivStringBytes = Generate128BitsOfRandomEntropy();
- //Console.WriteLine($"ivStringBytes: {Encoders.Hex.EncodeData(ivStringBytes)}");
+
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
- using (var symmetricKey = new AesManaged())
+ using (var aes = CreateAES())
{
- symmetricKey.GenerateIV();
- symmetricKey.BlockSize = 128;
- symmetricKey.Mode = CipherMode.CBC;
- symmetricKey.Padding = PaddingMode.PKCS7;
- using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, symmetricKey.IV))
+ aes.GenerateIV();
+ using (var encryptor = aes.CreateEncryptor(keyBytes, aes.IV))
{
using (var memoryStream = new MemoryStream())
{
+ memoryStream.Write(saltStringBytes, 0, saltStringBytes.Length);
+ memoryStream.Write(aes.IV, 0, aes.IV.Length);
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
- // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
- var cipherTextBytes = saltStringBytes;
- cipherTextBytes = cipherTextBytes.Concat(symmetricKey.IV).ToArray();
- cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
- memoryStream.Close();
cryptoStream.Close();
- return Convert.ToBase64String(cipherTextBytes);
}
+ var cipherTextBytes = memoryStream.ToArray();
+ memoryStream.Close();
+ return Convert.ToBase64String(cipherTextBytes);
}
}
}
@@ -59,32 +62,25 @@ namespace MagicalCryptoWallet.Crypto
public static string Decrypt(string cipherText, string passPhrase)
{
- // Get the complete stream of bytes that represent:
- // [32 bytes of Salt] + [16 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
- // Get the saltbytes by extracting the first 16 bytes from the supplied cipherText bytes.
- var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
- // Get the IV bytes by extracting the next 16 bytes from the supplied cipherText bytes.
- var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
- // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
- var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
+
+ using (var memoryStream = new MemoryStream(cipherTextBytesWithSaltAndIv))
+ {
+ using (var reader = new BinaryReader(memoryStream))
+ {
+ var saltStringBytes = reader.ReadBytes(Keysize / 8);
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
- using (var symmetricKey = new AesManaged())
- {
- symmetricKey.IV = ivStringBytes;
- symmetricKey.BlockSize = 128;
- symmetricKey.Mode = CipherMode.CBC;
- symmetricKey.Padding = PaddingMode.PKCS7;
- using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
+ using (var aes = CreateAES())
{
- using (var memoryStream = new MemoryStream(cipherTextBytes))
+ var ivStringBytes = reader.ReadBytes(Keysize / 8);
+ using (var decryptor = aes.CreateDecryptor(keyBytes, ivStringBytes))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
- var plainTextBytes = new byte[cipherTextBytes.Length];
+ var plainTextBytes = new byte[memoryStream.Length - memoryStream.Position];
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
@@ -95,16 +91,8 @@ namespace MagicalCryptoWallet.Crypto
}
}
}
+ }
- // private static int c = 0;
- // private static byte[] Generate128BitsOfRandomEntropy()
- // {
- // var s = (c % 2 == 0)
- // ? "ad8d01ed34fcd39e30d06dfa3e7dd9f5"
- // : "054afcb1e13a0d258ae423ed2f535f3c";
- // c++;
- // return Encoders.Hex.DecodeData(s);
- // }
private static byte[] Generate128BitsOfRandomEntropy()
{

Small refactoring and clean up