byte[] ReadEncryptedStorage(out EncryptionOptions options) { _storage.Ensure(); const int headerLength = sizeof(EncryptionOptions); if (_storage.Length <= headerLength) //Empty storage { options = EncryptionOptions.None; return(new byte[0]); } byte[] bytes; using (var fs = _storage.Read(out options)) { int index = 0; int count = (int)fs.Length - headerLength; if (options.IsZipped()) { using (var output = new MemoryStream()) using (var zipStream = new DeflateStream(fs, CompressionMode.Decompress)) { zipStream.CopyTo(output); output.Position = 0; bytes = output.ToArray(); } } else { bytes = new byte[count]; while (count > 0) { int n = fs.Read(bytes, index, count); index += n; count -= n; } } } return(bytes); }
public void Encrypt(IDictionary <string, T> values, byte[] password, EncryptionOptions options, ushort saltSize, int iterations) { byte[] bytes; if (options.WriteOffsets()) { byte[] offsets; bytes = _security.EncryptDictionary(values, password, out offsets, options, saltSize, iterations); _storage.WriteIndex(offsets); offsets.Clear(); } else { bytes = _security.EncryptDictionary(values, password, options, saltSize, iterations); } using (var fs = _storage.Create(options)) { var writeStream = fs; var isZipped = options.IsZipped(); if (isZipped) { writeStream = new DeflateStream(fs, CompressionMode.Compress); } try { writeStream.Write(bytes, 0, bytes.Length); } finally { if (isZipped) { writeStream.Dispose(); } } } bytes.Clear(); }
public static bool CanMerge(this EncryptionOptions options) => !options.AreKeysEncrypted() && !options.IsZipped() && !options.IsResultEncrypted();
T DecryptUsingOffsetsWithoutEncryptedResult(string key, byte[] password, int iterations, byte[] indexes, byte[] keyBytes, EncryptionOptions options) { var keysAreEncrypted = options.AreKeysEncrypted(); using (var fs = _storage.Read()) { var readStream = fs; var isZipped = options.IsZipped(); if (isZipped) { fs.Seek(sizeof(EncryptionOptions), SeekOrigin.Begin); //skip header readStream = new MemoryStream(); using (var zipStream = new DeflateStream(fs, CompressionMode.Decompress)) { var bytes = new byte[sizeof(EncryptionOptions)]; fixed(byte *b = bytes) UnsafeNativeMethods.memcpy(b, &options, sizeof(EncryptionOptions)); readStream.Write(bytes, 0, sizeof(EncryptionOptions)); zipStream.CopyTo(readStream); readStream.Position = 0; } } try { fixed(byte *b = indexes) { var ptr = (ushort *)(b); var length = new byte[sizeof(ushort)]; do { readStream.Seek(*ptr, SeekOrigin.Begin); readStream.Read(length, 0, sizeof(ushort)); if (!keysAreEncrypted) { fixed(byte *k = length) { if (*(ushort *)k != keyBytes.Length) { ptr++; continue; } } } byte[] content; fixed(byte *k = length) content = new byte[*(ushort *)k]; readStream.Read(length, 0, length.Length); //contentLength readStream.Read(content, 0, content.Length); //key if (keysAreEncrypted) { content = Security.Decrypt(content, password, iterations); } var keysMatch = UnsafeNativeMethods.memcmp(content, keyBytes); if (keysAreEncrypted) { content.Clear(); } if (keysMatch) { fixed(byte *k = length) content = new byte[*(ushort *)k]; //content length readStream.Read(content, 0, content.Length); var decryptedValue = _security.DecryptValue(content, password, iterations); content.Clear(); return(decryptedValue); } ptr++; } while (((byte *)ptr - b) != indexes.Length); } } finally { if (isZipped) { readStream.Dispose(); } } } throw Error.KeyNotFound(key); }