1 year ago

#359255

test-img

bBekan

Asp.Net StreamReader incorrectly reads string

I'm currently working on a simple AesGcm encoder that stores passwords for certain domains in a text file (It's a lab assignment). I'm having trouble fetching stored strings back from the file and I haven't a clue how to fix it. Any help is welcome!

Here is a part of my code:

{
    using (var aes = new AesGcm(Encoding.UTF8.GetBytes(masterPassword.PadRight(32))))
    {
        var nonce = new byte[12];
        RandomNumberGenerator.Fill(nonce);
        var plaintextBytes = Encoding.UTF8.GetBytes(masterPassword);
        var ciphertext = new byte[plaintextBytes.Length];
        var tag = new byte[16];

        aes.Encrypt(nonce, plaintextBytes, ciphertext, tag);

        using (var fileWriter = new FileStream("TestData.txt", FileMode.OpenOrCreate, FileAccess.Write))
        {
            using(var streamWriter = new StreamWriter(fileWriter, System.Text.Encoding.UTF8))
            {
                var nonceString = System.Text.Encoding.UTF8.GetString(nonce);
                var cipherTextString = System.Text.Encoding.UTF8.GetString(ciphertext);
                var tagString = System.Text.Encoding.UTF8.GetString(tag);
                streamWriter.Write($"{nonceString}|{tagString}|{cipherTextString}\n");
            }
        }
    }
}

After I Initialize the text file (Required by the task) I need to put some info in e.g. (put masterPassword domain password). Before I do that i first validate the user by seeing if the masterPassword matches with the one i encoded on initialization using this function:

{
    using (var aes = new AesGcm(Encoding.UTF8.GetBytes(masterPassword.PadRight(32))))
    {
        using(var reader = new StreamReader("TestData.txt", System.Text.Encoding.UTF8))
        {
            var line = reader.ReadLine().Split("|");

            foreach(var s in line)
                Console.WriteLine(s);

            var nonce = Encoding.UTF8.GetBytes(line[0]);
            var tag = Encoding.UTF8.GetBytes(line[1]);
            var ciphertext = Encoding.UTF8.GetBytes(line[2]);

            var plaintext = new byte[ciphertext.Length];

            aes.Decrypt(nonce, ciphertext, tag, plaintext);

            if (Encoding.UTF8.GetString(plaintext).Equals(masterPassword))
                return true;
            return false;
        }
    }
}

But for some reason the data is improperly read and instead of getting a nonce of size 12 I get a nonce of size 20.

Here is the complete code for the purpose of testing:

using System.Security.Cryptography;
using System.Text;

var arguments = Environment.GetCommandLineArgs();

switch (arguments[1])
{
    case "init":
         Initialize(arguments[2]);
        break;
    case "put":
        if(Validate(arguments[2]))
         //EncryptData(arguments[2], arguments[3], arguments[4]);
        else
            Console.WriteLine("Unauthorized!");
        break;
    case "get":
            //DecryptAsync(arguments[2], arguments[3]);
        break;
    default:
        Console.WriteLine("Invalid arguments");
        break;
}

void Initialize(string masterPassword)
{
    using (var aes = new AesGcm(Encoding.UTF8.GetBytes(masterPassword.PadRight(32))))
    {
        var nonce = new byte[12];
        RandomNumberGenerator.Fill(nonce);
        var plaintextBytes = Encoding.UTF8.GetBytes(masterPassword);
        var ciphertext = new byte[plaintextBytes.Length];
        var tag = new byte[16];

        aes.Encrypt(nonce, plaintextBytes, ciphertext, tag);

        using (var fileWriter = new FileStream("TestData.txt", FileMode.OpenOrCreate, FileAccess.Write))
        {
            using(var streamWriter = new StreamWriter(fileWriter, System.Text.Encoding.UTF8))
            {
                var nonceString = System.Text.Encoding.UTF8.GetString(nonce);
                var cipherTextString = System.Text.Encoding.UTF8.GetString(ciphertext);
                var tagString = System.Text.Encoding.UTF8.GetString(tag);
                streamWriter.Write($"{nonceString}|{tagString}|{cipherTextString}\n");
            }
        }
    }
}

/*void EncryptData(string masterPassword, string domain, string password)
{
    using (var aes = new AesGcm(Encoding.UTF8.GetBytes(masterPassword.PadRight(32))))
    {
        var nonce = new byte[AesGcm.NonceByteSizes.MaxSize];
        RandomNumberGenerator.Fill(nonce);
        var plaintextBytes = Encoding.UTF8.GetBytes("|" + domain + "|" + password);
        var ciphertext = new byte[plaintextBytes.Length];
        var tag = new byte[AesGcm.TagByteSizes.MaxSize];

        using (var fileWriter = new FileStream("TestData.txt", FileMode.Open, FileAccess.Write))
        {
            fileWriter.Seek(0, SeekOrigin.End);
            var separator = Encoding.UTF8.GetBytes("|");
            var newLine = Encoding.UTF8.GetBytes("\n");
            byte[] buffer = nonce.Concat(separator).ToArray();
            aes.Encrypt(nonce, plaintextBytes, ciphertext, tag);
            buffer.Concat(tag).Concat(separator).Concat(ciphertext).Concat(plaintextBytes).Concat(newLine).ToArray();
            fileWriter.Write(buffer, 0, buffer.Length);
        }
    }
}*/

bool Validate(string masterPassword)
{
    using (var aes = new AesGcm(Encoding.UTF8.GetBytes(masterPassword.PadRight(32))))
    {
        using(var reader = new StreamReader("TestData.txt", System.Text.Encoding.UTF8))
        {
            var line = reader.ReadLine().Split("|");

            foreach(var s in line)
                Console.WriteLine(s);

            var nonce = Encoding.UTF8.GetBytes(line[0]);
            var tag = Encoding.UTF8.GetBytes(line[1]);
            var ciphertext = Encoding.UTF8.GetBytes(line[2]);

            var plaintext = new byte[ciphertext.Length];

            aes.Decrypt(nonce, ciphertext, tag, plaintext);

            if (Encoding.UTF8.GetString(plaintext).Equals(masterPassword))
                return true;
            return false;
        }
    }
}

c#

encryption

filereader

filewriter

aes-gcm

0 Answers

Your Answer

Accepted video resources