1

Several users have encountered strange issues with my app/game. They reported that their save files have become invalid. I've tried to investigate the problem and haven't found anything.

Here is a pipeline:

  1. in-game data converts to json file (string)
  2. json file converts UTF8 bytes
  3. UTF8 bytes goes thru this encryption method (using AES)

Save file extension is .dat

This is a first game where I decided to use step #3 (save data with encryption) and I didn't found anything strange and like that in testcases and on test stands.

After I've got some save files from involved users, I saw that all of those files has valid non-zero length, but have only zero bytes.

This is an example of one of those files: only zero bytes here

Here is a code of encryption:

public static byte[] Encrypt(byte[] clearBytes, string encyptionKey)
{
    using (var algorythm = Aes.Create())
    {
        algorythm.Mode = CipherMode.CBC;
        algorythm.Padding = PaddingMode.PKCS7;
        var encryptionBytes = _encoding.GetBytes(encyptionKey);
        using (var pdb = new Rfc2898DeriveBytes(encryptionBytes, _salt, _iterations, _hashAlgorithm))
        {
            algorythm.Key = pdb.GetBytes(32);
            algorythm.IV = pdb.GetBytes(16);
            using (var encryptor = algorythm.CreateEncryptor())
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(clearBytes, 0, clearBytes.Length);
                    }
                    return ms.ToArray();
                }
            }
        }
    }
}

Here is a code of save file to file system:

public bool Save(string relativePath, byte[] bytes)
{
    var absolutePath = Path.Combine(_applicationDataPath, relativePath);
    var fi = new FileInfo(absolutePath);
    var di = fi.Directory;

    try
    {
        if (!di.Exists)
            di.Create();

        var exists = fi.Exists;
        using (var fs = exists ? fi.OpenWrite() : fi.Create())
        {
            fs.SetLength(0);
            fs.Seek(0, SeekOrigin.Begin);

            using (var ms = new MemoryStream(bytes))
            {
                ms.CopyTo(fs);
                ms.Flush();

                return true;
            }
        }
    }
    catch (Exception ex)
    {
        Debug.LogException(ex);
        return false;
    }
}

Everything is working good if I remove encryption, no reports with broken save files there. The problem is I can't reproduce this bug on my own computer.

13
  • 2
    Welcome to Stack Overflow. Please take the tour to learn how Stack Overflow works and read How to Ask on how to improve the quality of your question. Then edit your question to include your source code as a working minimal reproducible example, which can be compiled and tested by others to provide an answer faster. Also explain where/how you see the zero bytes. The MCVE should show how you write the files, how you read the files and how you decrypt the files. Commented Oct 12 at 7:12
  • What .net version are they using? Commented Oct 12 at 9:10
  • It's Unity Engine 2022.3.62f2 with .NET Standard 2.1 api compatibility level Commented Oct 12 at 9:47
  • 2
    On a side note: ms.Flush doesn't do what you think it does and is completely unnecessary. You also don't need the memorystream at all, you can just Write the bytes. Also why write the encrypted bytes to a memorystream to turn into an array to turn into a memroystream to write to a file, why not just wrap the CryptoStream directly over the file? And why Base64 the JSON rather than just encrypting the UTF8 JSON directly? I hope the encryption key isn't hard-coded in your app... Commented Oct 12 at 11:35
  • 3
    To answer your question in the caption, yes that's theoretically possible, but the chance of getting that would be 1 in 256 to the power of the length of the array, so that's probably not what's happening. Commented Oct 12 at 13:32

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.