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); }