Esempio n. 1
0
        public static bool Save(string storagePassword)
        {
            Debug.Log($"[mStorage] Save file ({DbPath})");
            var directory = Path.GetDirectoryName(DbPath);

            if (!Directory.Exists(directory))
            {
                try
                {
                    // ReSharper disable once AssignNullToNotNullAttribute
                    Directory.CreateDirectory(directory);
                }
                catch (Exception e)
                {
                    Debug.LogWarning($"[mStorage] Create directory ({DbPath}) error ({e})");
                    return(false);
                }
            }

            Stream stream;

            try
            {
                stream = File.Open(DbPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                stream.SetLength(0);
            }
            catch (Exception e)
            {
                Debug.LogWarning($"[mStorage] Save file ({DbPath}) error ({e})");
                return(false);
            }

            stream.WriteStruct(new DataFileVersionHeader
            {
                MagicArray = new[] { 'M', 'B', 'I', 'N' },
                Version    = Version
            });
            stream.Seek(Marshal.SizeOf <DataFileHeader>(), SeekOrigin.Current);

            // encryption data
            var symmetricKey = new RijndaelManaged
            {
                Mode    = CipherMode.CBC,
                Padding = PaddingMode.Zeros
            };
            var storageKeyBytes = new Rfc2898DeriveBytes(storagePassword,
                                                         Encoding.UTF8.GetBytes(SaltKey)).GetBytes(KeyLength / 8);
            var encryptor = symmetricKey.CreateEncryptor(storageKeyBytes,
                                                         Encoding.UTF8.GetBytes(VIKey));

            var dataStart    = stream.Position;
            var cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write);

            foreach (var pair in _data)
            {
                var keyBytes = Encoding.UTF8.GetBytes(pair.Key);
                cryptoStream.WriteStruct(new DataFileItem()
                {
                    KeySize  = (byte)keyBytes.Length,
                    DataSize = pair.Value.Length,
                });
                cryptoStream.Write(keyBytes, 0, keyBytes.Length);
                cryptoStream.Write(pair.Value, 0, pair.Value.Length);
            }
            cryptoStream.FlushFinalBlock();

            var encryptedSize = stream.Position - dataStart;

            stream.Seek(Marshal.SizeOf <DataFileVersionHeader>(), SeekOrigin.Begin);
            stream.WriteStruct(new DataFileHeader
            {
                ItemsNum      = _data.Count,
                EncryptedSize = encryptedSize,
            });

            cryptoStream.Close();
            stream.Close();
            return(true);
        }