jj: FileContainer Version 0.0.2
This commit is contained in:
parent
0f105b6ebf
commit
7b2ae3abc3
@ -3,7 +3,7 @@ Imports System.IO
|
|||||||
Imports Microsoft.VisualStudio.TestTools.UnitTesting
|
Imports Microsoft.VisualStudio.TestTools.UnitTesting
|
||||||
Imports DigitalData.Modules.Filesystem
|
Imports DigitalData.Modules.Filesystem
|
||||||
Imports DigitalData.Modules.Logging
|
Imports DigitalData.Modules.Logging
|
||||||
Imports DigitalData.Modules.Filesystem.FileContainer
|
Imports DigitalData.Modules.Filesystem.FileContainerOld
|
||||||
|
|
||||||
<TestClass()> Public Class FileContainerTest
|
<TestClass()> Public Class FileContainerTest
|
||||||
|
|
||||||
@ -43,18 +43,18 @@ Imports DigitalData.Modules.Filesystem.FileContainer
|
|||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
<ExpectedException(GetType(ArgumentNullException))>
|
<ExpectedException(GetType(ArgumentNullException))>
|
||||||
Public Sub TestConstructorPasswordNothing()
|
Public Sub TestConstructorPasswordNothing()
|
||||||
Dim oContainer = New FileContainer(_logConfig, Nothing)
|
Dim oContainer = New FileContainerOld(_logConfig, Nothing)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
Public Sub TestConstructorValidPassword()
|
Public Sub TestConstructorValidPassword()
|
||||||
Dim oContainer = New FileContainer(_logConfig, "foobar")
|
Dim oContainer = New FileContainerOld(_logConfig, "foobar")
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
<ExpectedException(GetType(FileNotFoundException))>
|
<ExpectedException(GetType(FileNotFoundException))>
|
||||||
Public Sub TestAddFileNonExistentFilePath()
|
Public Sub TestAddFileNonExistentFilePath()
|
||||||
Dim oContainer As New FileContainer(_logConfig, PASSWORD)
|
Dim oContainer As New FileContainerOld(_logConfig, PASSWORD)
|
||||||
|
|
||||||
oContainer.AddFile(FILENAME_NONEXISTENT)
|
oContainer.AddFile(FILENAME_NONEXISTENT)
|
||||||
End Sub
|
End Sub
|
||||||
@ -62,21 +62,21 @@ Imports DigitalData.Modules.Filesystem.FileContainer
|
|||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
<ExpectedException(GetType(ArgumentNullException))>
|
<ExpectedException(GetType(ArgumentNullException))>
|
||||||
Public Sub TestAddFileNothingFilePath()
|
Public Sub TestAddFileNothingFilePath()
|
||||||
Dim oContainer As New FileContainer(_logConfig, PASSWORD)
|
Dim oContainer As New FileContainerOld(_logConfig, PASSWORD)
|
||||||
|
|
||||||
oContainer.AddFile(Nothing)
|
oContainer.AddFile(Nothing)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
Public Sub TestAddFileValidFilePath()
|
Public Sub TestAddFileValidFilePath()
|
||||||
Dim oContainer As New FileContainer(_logConfig, PASSWORD)
|
Dim oContainer As New FileContainerOld(_logConfig, PASSWORD)
|
||||||
|
|
||||||
oContainer.AddFile(FILENAME_VALID)
|
oContainer.AddFile(FILENAME_VALID)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
Public Sub TestFilesPropertyCount()
|
Public Sub TestFilesPropertyCount()
|
||||||
Dim oContainer As New FileContainer(_logConfig, PASSWORD)
|
Dim oContainer As New FileContainerOld(_logConfig, PASSWORD)
|
||||||
|
|
||||||
oContainer.AddFile(FILENAME_VALID)
|
oContainer.AddFile(FILENAME_VALID)
|
||||||
Assert.AreEqual(1, oContainer.Files.Count)
|
Assert.AreEqual(1, oContainer.Files.Count)
|
||||||
@ -84,7 +84,7 @@ Imports DigitalData.Modules.Filesystem.FileContainer
|
|||||||
|
|
||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
Public Sub TestFilesPropertyType()
|
Public Sub TestFilesPropertyType()
|
||||||
Dim oContainer As New FileContainer(_logConfig, PASSWORD)
|
Dim oContainer As New FileContainerOld(_logConfig, PASSWORD)
|
||||||
|
|
||||||
oContainer.AddFile(FILENAME_VALID)
|
oContainer.AddFile(FILENAME_VALID)
|
||||||
Assert.IsInstanceOfType(oContainer.Files.First(), GetType(FileEntry))
|
Assert.IsInstanceOfType(oContainer.Files.First(), GetType(FileEntry))
|
||||||
@ -93,7 +93,7 @@ Imports DigitalData.Modules.Filesystem.FileContainer
|
|||||||
|
|
||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
Public Sub TestSaveValidPath()
|
Public Sub TestSaveValidPath()
|
||||||
Dim oContainer As New FileContainer(_logConfig, PASSWORD)
|
Dim oContainer As New FileContainerOld(_logConfig, PASSWORD)
|
||||||
|
|
||||||
oContainer.AddFile(FILENAME_VALID)
|
oContainer.AddFile(FILENAME_VALID)
|
||||||
oContainer.Save(CONTAINER_FILE_VALID)
|
oContainer.Save(CONTAINER_FILE_VALID)
|
||||||
@ -104,7 +104,7 @@ Imports DigitalData.Modules.Filesystem.FileContainer
|
|||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
<ExpectedException(GetType(UnauthorizedAccessException))>
|
<ExpectedException(GetType(UnauthorizedAccessException))>
|
||||||
Public Sub TestSavePathNotWritable()
|
Public Sub TestSavePathNotWritable()
|
||||||
Dim oContainer As New FileContainer(_logConfig, PASSWORD)
|
Dim oContainer As New FileContainerOld(_logConfig, PASSWORD)
|
||||||
|
|
||||||
oContainer.AddFile(FILENAME_VALID)
|
oContainer.AddFile(FILENAME_VALID)
|
||||||
oContainer.Save(CONTAINER_FILE_NOWRITE)
|
oContainer.Save(CONTAINER_FILE_NOWRITE)
|
||||||
@ -112,13 +112,13 @@ Imports DigitalData.Modules.Filesystem.FileContainer
|
|||||||
|
|
||||||
<TestMethod()>
|
<TestMethod()>
|
||||||
Public Sub TestSaveLoadSameContents()
|
Public Sub TestSaveLoadSameContents()
|
||||||
Dim oContainer As FileContainer
|
Dim oContainer As FileContainerOld
|
||||||
Dim oFileContents As String = "dasisteintest"
|
Dim oFileContents As String = "dasisteintest"
|
||||||
|
|
||||||
' Test String in Textdatei schreiben
|
' Test String in Textdatei schreiben
|
||||||
IO.File.WriteAllText(FILENAME_VALID, oFileContents)
|
IO.File.WriteAllText(FILENAME_VALID, oFileContents)
|
||||||
|
|
||||||
oContainer = New FileContainer(_logConfig, PASSWORD)
|
oContainer = New FileContainerOld(_logConfig, PASSWORD)
|
||||||
' Textdatei zu einem Container hinzufügen
|
' Textdatei zu einem Container hinzufügen
|
||||||
oContainer.AddFile(FILENAME_VALID)
|
oContainer.AddFile(FILENAME_VALID)
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ Imports DigitalData.Modules.Filesystem.FileContainer
|
|||||||
IO.File.Delete(FILENAME_VALID)
|
IO.File.Delete(FILENAME_VALID)
|
||||||
|
|
||||||
oContainer = Nothing
|
oContainer = Nothing
|
||||||
oContainer = New FileContainer(_logConfig, PASSWORD)
|
oContainer = New FileContainerOld(_logConfig, PASSWORD)
|
||||||
' Container wieder laden
|
' Container wieder laden
|
||||||
oContainer.Load(CONTAINER_FILE_VALID)
|
oContainer.Load(CONTAINER_FILE_VALID)
|
||||||
|
|
||||||
|
|||||||
@ -8,12 +8,19 @@ Imports DigitalData.Modules.Logging
|
|||||||
Friend Class Encryption
|
Friend Class Encryption
|
||||||
' This constant is used to determine the keysize of the encryption algorithm in bits.
|
' This constant is used to determine the keysize of the encryption algorithm in bits.
|
||||||
' We divide this by 8 within the code below to get the equivalent number of bytes.
|
' We divide this by 8 within the code below to get the equivalent number of bytes.
|
||||||
Private Const KEYSIZE As Integer = 256
|
Private Const KEY_SIZE As Integer = 256
|
||||||
' This constant determines the number of iterations for the password bytes generation function.
|
' This constant determines the number of iterations for the password bytes generation function.
|
||||||
Private Const DERIVATION_ITERATIONS As Integer = 1000
|
Private Const DERIVATION_ITERATIONS As Integer = 1000
|
||||||
|
Private Const BLOCK_SIZE As Integer = 256
|
||||||
|
|
||||||
|
Private _paddingMode As PaddingMode = PaddingMode.Zeros
|
||||||
|
Private _cipherMode As CipherMode = CipherMode.CBC
|
||||||
|
|
||||||
Private ReadOnly _password As String
|
Private ReadOnly _password As String
|
||||||
Private _logger As Logger
|
Private _logger As Logger
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Public Sub New(LogConfig As LogConfig, Password As String)
|
Public Sub New(LogConfig As LogConfig, Password As String)
|
||||||
_logger = LogConfig.GetLogger()
|
_logger = LogConfig.GetLogger()
|
||||||
|
|
||||||
@ -37,11 +44,12 @@ Friend Class Encryption
|
|||||||
Dim oSaltStringBytes = Generate256BitsOfRandomEntropy()
|
Dim oSaltStringBytes = Generate256BitsOfRandomEntropy()
|
||||||
Dim oIvStringBytes = Generate256BitsOfRandomEntropy()
|
Dim oIvStringBytes = Generate256BitsOfRandomEntropy()
|
||||||
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
||||||
Dim oKeyBytes = oPassword.GetBytes(KEYSIZE / 8)
|
Dim oKeyBytes = oPassword.GetBytes(KEY_SIZE / 8)
|
||||||
Using oSymmetricKey = New RijndaelManaged()
|
Using oSymmetricKey = New RijndaelManaged()
|
||||||
oSymmetricKey.BlockSize = 256
|
oSymmetricKey.BlockSize = BLOCK_SIZE
|
||||||
oSymmetricKey.Mode = CipherMode.CBC
|
oSymmetricKey.Mode = _cipherMode
|
||||||
oSymmetricKey.Padding = PaddingMode.PKCS7
|
oSymmetricKey.Padding = _paddingMode
|
||||||
|
|
||||||
Using oEncryptor = oSymmetricKey.CreateEncryptor(oKeyBytes, oIvStringBytes)
|
Using oEncryptor = oSymmetricKey.CreateEncryptor(oKeyBytes, oIvStringBytes)
|
||||||
Using oMemoryStream = New MemoryStream()
|
Using oMemoryStream = New MemoryStream()
|
||||||
Using oCryptoStream = New CryptoStream(oMemoryStream, oEncryptor, CryptoStreamMode.Write)
|
Using oCryptoStream = New CryptoStream(oMemoryStream, oEncryptor, CryptoStreamMode.Write)
|
||||||
@ -76,18 +84,18 @@ Friend Class Encryption
|
|||||||
' Get the complete stream of bytes that represent:
|
' Get the complete stream of bytes that represent:
|
||||||
' [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
|
' [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
|
||||||
' Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
|
' Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
|
||||||
Dim oSaltStringBytes = cipherTextBytesWithSaltAndIv.Take(KEYSIZE / 8).ToArray()
|
Dim oSaltStringBytes = cipherTextBytesWithSaltAndIv.Take(KEY_SIZE / 8).ToArray()
|
||||||
' Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
|
' Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
|
||||||
Dim oIvStringBytes = cipherTextBytesWithSaltAndIv.Skip(KEYSIZE / 8).Take(KEYSIZE / 8).ToArray()
|
Dim oIvStringBytes = cipherTextBytesWithSaltAndIv.Skip(KEY_SIZE / 8).Take(KEY_SIZE / 8).ToArray()
|
||||||
' Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
|
' Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
|
||||||
Dim oCipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((KEYSIZE / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((KEYSIZE / 8) * 2)).ToArray()
|
Dim oCipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((KEY_SIZE / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((KEY_SIZE / 8) * 2)).ToArray()
|
||||||
|
|
||||||
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
||||||
Dim oKeyBytes = oPassword.GetBytes(KEYSIZE / 8)
|
Dim oKeyBytes = oPassword.GetBytes(KEY_SIZE / 8)
|
||||||
Using oSymmetricKey = New RijndaelManaged()
|
Using oSymmetricKey = New RijndaelManaged()
|
||||||
oSymmetricKey.BlockSize = 256
|
oSymmetricKey.BlockSize = BLOCK_SIZE
|
||||||
oSymmetricKey.Mode = CipherMode.CBC
|
oSymmetricKey.Mode = _cipherMode
|
||||||
oSymmetricKey.Padding = PaddingMode.PKCS7
|
oSymmetricKey.Padding = _paddingMode
|
||||||
Using oDecryptor = oSymmetricKey.CreateDecryptor(oKeyBytes, oIvStringBytes)
|
Using oDecryptor = oSymmetricKey.CreateDecryptor(oKeyBytes, oIvStringBytes)
|
||||||
Using oMemoryStream = New MemoryStream(oCipherTextBytes)
|
Using oMemoryStream = New MemoryStream(oCipherTextBytes)
|
||||||
Using oCryptoStream = New CryptoStream(oMemoryStream, oDecryptor, CryptoStreamMode.Read)
|
Using oCryptoStream = New CryptoStream(oMemoryStream, oDecryptor, CryptoStreamMode.Read)
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
Imports System.IO
|
Imports System.IO
|
||||||
Imports System.Runtime.Serialization.Formatters.Binary
|
|
||||||
Imports DigitalData.Modules.Logging
|
Imports DigitalData.Modules.Logging
|
||||||
|
Imports ProtoBuf
|
||||||
|
|
||||||
''' <module>FileContainer</module>
|
''' <module>FileContainer</module>
|
||||||
''' <version>0.0.0.1</version>
|
''' <version>0.0.0.2</version>
|
||||||
''' <date>16.11.2018</date>
|
''' <date>21.11.2018</date>
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' File Container for securely saving files
|
''' File Container for securely saving files
|
||||||
''' </summary>
|
''' </summary>
|
||||||
@ -13,277 +13,191 @@ Imports DigitalData.Modules.Logging
|
|||||||
''' </dependencies>
|
''' </dependencies>
|
||||||
''' <params>
|
''' <params>
|
||||||
''' LogConfig, DigitalData.Module.Logging.LogConfig
|
''' LogConfig, DigitalData.Module.Logging.LogConfig
|
||||||
''' A LogConfig object
|
''' A LogConfig object
|
||||||
|
''' Password, String
|
||||||
|
''' The Password to Encrypt
|
||||||
|
''' Path, String
|
||||||
|
''' The Path to save/load the container
|
||||||
''' </params>
|
''' </params>
|
||||||
''' <props>
|
|
||||||
''' </props>
|
|
||||||
''' <example>
|
''' <example>
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
''' dim oContainer = Container.Create(logConfig, "pass", "E:\some.container")
|
||||||
|
''' dim oContainer = Container.Load(logConfig, "pass", "E:\some.container")
|
||||||
|
'''
|
||||||
|
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
|
||||||
|
''' oContainer.Save()
|
||||||
|
'''
|
||||||
|
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
|
||||||
|
''' oContainer.Contents = oSomeData
|
||||||
|
''' oContainer.Save()
|
||||||
|
'''
|
||||||
|
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
|
||||||
|
''' oContainer.Load()
|
||||||
|
''' dim oContents = oContainer.Contents
|
||||||
|
'''
|
||||||
|
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
|
||||||
|
''' oContainer.Load()
|
||||||
|
''' oContainer.Contents = oSomeOtherData
|
||||||
|
''' oContainer.Save()
|
||||||
|
''' oContainer.SaveAs("E:\some2.container")
|
||||||
''' </example>
|
''' </example>
|
||||||
''' <remarks>
|
|
||||||
''' </remarks>
|
|
||||||
Public Class FileContainer
|
Public Class FileContainer
|
||||||
Private _files As List(Of FileEntry)
|
|
||||||
Private _crypto As Encryption
|
Private _crypto As Encryption
|
||||||
Private _compression As Compression
|
Private _compression As Compression
|
||||||
Private _formatter As BinaryFormatter
|
|
||||||
Private _containerId As Guid
|
Private _containerId As Guid
|
||||||
Private _inner As FileContainerInner
|
Private _inner As FileContainerInner
|
||||||
Private _logger As Logger
|
Private _logger As Logger
|
||||||
Private _logConfig As LogConfig
|
Private _logConfig As LogConfig
|
||||||
|
Private _path As String
|
||||||
|
|
||||||
<Serializable>
|
Public Property Contents As Byte()
|
||||||
Public Class FileEntry
|
|
||||||
Public FileId As String
|
|
||||||
Public Contents As Byte()
|
|
||||||
Public CreatedAt As DateTime
|
|
||||||
Public UpdatedAt As DateTime
|
|
||||||
End Class
|
|
||||||
|
|
||||||
<Serializable>
|
|
||||||
Public Class FileContainerInner
|
|
||||||
Public Files As List(Of FileEntry)
|
|
||||||
Public ContainerID As Guid
|
|
||||||
Public CreatedAt As DateTime
|
|
||||||
Public UpdatedAt As DateTime
|
|
||||||
End Class
|
|
||||||
|
|
||||||
Public ReadOnly Property ContainerId As String
|
|
||||||
Get
|
Get
|
||||||
If _inner Is Nothing Then
|
Return _inner.Contents
|
||||||
Return Nothing
|
End Get
|
||||||
End If
|
Set(value As Byte())
|
||||||
|
_inner.Contents = value
|
||||||
Return _inner.ContainerID.ToString
|
End Set
|
||||||
|
End Property
|
||||||
|
Public Property Extension As String
|
||||||
|
Get
|
||||||
|
Return _inner.Extension
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
_inner.Extension = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Public ReadOnly Property FileId As String
|
||||||
|
Get
|
||||||
|
Return _inner.FileId
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Public ReadOnly Property CreatedAt As String
|
||||||
|
Get
|
||||||
|
Return _inner.CreatedAt
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Public ReadOnly Property UpdatedAt As String
|
||||||
|
Get
|
||||||
|
Return _inner.UpdatedAt
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
''' <summary>
|
Public Shared Function Create(LogConfig As LogConfig, Password As String) As FileContainer
|
||||||
''' Gibt eine Auflistung der Dateien in Container zurück.
|
Dim oContainer = New FileContainer(LogConfig, Password)
|
||||||
''' </summary>
|
Return oContainer
|
||||||
''' <returns>Eine Liste von Objekten der Klasse FileContainer.FileEntry</returns>
|
End Function
|
||||||
Public ReadOnly Property Files As List(Of FileEntry)
|
|
||||||
Get
|
|
||||||
If _inner Is Nothing Then
|
|
||||||
Return Nothing
|
|
||||||
End If
|
|
||||||
|
|
||||||
Return _inner.Files
|
Public Shared Function Load(LogConfig As LogConfig, Password As String, Path As String) As FileContainer
|
||||||
End Get
|
Dim oContainer = New FileContainer(LogConfig, Password, Path)
|
||||||
End Property
|
oContainer.Load()
|
||||||
|
Return oContainer
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Sub New(LogConfig As LogConfig, Password As String, Path As String)
|
||||||
|
_logger = LogConfig.GetLogger()
|
||||||
|
_crypto = New Encryption(LogConfig, Password)
|
||||||
|
_compression = New Compression(LogConfig)
|
||||||
|
_inner = New FileContainerInner()
|
||||||
|
_path = Path
|
||||||
|
End Sub
|
||||||
|
|
||||||
''' <summary>
|
|
||||||
''' Erstellt eine Representation eines Datei Containers, der mit dem angegebenen Passwort geschützt ist.
|
|
||||||
''' Ist für das speichern von neuen Containern und für das laden vorhandener Container nötig.
|
|
||||||
''' </summary>
|
|
||||||
''' <param name="Password">Das Passwort, mit dem der Container ver- und entschlüsselt wird</param>
|
|
||||||
''' <example>
|
|
||||||
''' Dim password = "meinpasswort"
|
|
||||||
''' Dim container = new FileContainer(password)
|
|
||||||
''' </example>
|
|
||||||
Public Sub New(LogConfig As LogConfig, Password As String)
|
Public Sub New(LogConfig As LogConfig, Password As String)
|
||||||
_logger = LogConfig.GetLogger()
|
_logger = LogConfig.GetLogger()
|
||||||
_crypto = New Encryption(LogConfig, Password)
|
_crypto = New Encryption(LogConfig, Password)
|
||||||
_compression = New Compression(LogConfig)
|
_compression = New Compression(LogConfig)
|
||||||
_formatter = New BinaryFormatter
|
_inner = New FileContainerInner()
|
||||||
_inner = New FileContainerInner() With {
|
|
||||||
.Files = New List(Of FileEntry),
|
|
||||||
.ContainerID = Guid.NewGuid(),
|
|
||||||
.CreatedAt = New DateTime()
|
|
||||||
}
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
''' <summary>
|
Public Sub SetFile(Contents As Byte(), Extension As String)
|
||||||
''' Speichert einen Datei Container am angegebenen Pfad.
|
_inner.Contents = Contents
|
||||||
''' Davor werden die Dateien in Files komprimiert und dann verschlüsselt.
|
_inner.Extension = Extension
|
||||||
''' </summary>
|
End Sub
|
||||||
''' <param name="Path">Der Pfad mit Dateiname, unter dem der Container abgelegt wird.</param>
|
|
||||||
''' <see cref="Files"/>
|
|
||||||
''' <example>
|
|
||||||
''' container.AddFile("datei1.txt")
|
|
||||||
''' container.AddFile("datei2.pdf")
|
|
||||||
''' container.Save("container.enc")
|
|
||||||
''' </example>
|
|
||||||
Public Sub Save(Path As String)
|
|
||||||
Try
|
|
||||||
' 1. Serialize
|
|
||||||
Dim oFileContainerInner As Byte() = Serialize(_inner)
|
|
||||||
' 2. Compress
|
|
||||||
Dim oFileContainerCompressed As Byte() = _compression.Compress(oFileContainerInner)
|
|
||||||
' 3. Encrypt
|
|
||||||
Dim oFileContainerEncrypted As Byte() = _crypto.Encrypt(oFileContainerCompressed)
|
|
||||||
|
|
||||||
BytesToFile(oFileContainerEncrypted, Path)
|
Public Sub Save()
|
||||||
|
If IsNothing(_path) Then
|
||||||
|
Throw New ArgumentException("Path not set")
|
||||||
|
End If
|
||||||
|
|
||||||
|
SaveAs(_path)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub SaveAs(Path As String)
|
||||||
|
Try
|
||||||
|
WriteBytesToFile(TransformToBytes(_inner), Path)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
_logger.Error(ex)
|
_logger.Error(ex)
|
||||||
Throw ex
|
Throw ex
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
''' <summary>
|
Public Sub Load()
|
||||||
''' Speichert einen Datei Container am angegebenen Pfad.
|
If IsNothing(_path) Then
|
||||||
''' Davor werden die Dateien in Files komprimiert und dann verschlüsselt.
|
Throw New ArgumentException("Path not set")
|
||||||
''' </summary>
|
End If
|
||||||
''' <param name="Path">Der Pfad mit Dateiname, unter dem der Container abgelegt wird.</param>
|
|
||||||
''' <example>
|
LoadFrom(_path)
|
||||||
''' Public Async Sub foobar()
|
End Sub
|
||||||
''' ...
|
|
||||||
''' container.AddFile("datei1.txt")
|
Public Sub LoadFrom(Path As String)
|
||||||
''' container.AddFile("datei2.pdf")
|
|
||||||
''' await container.SaveAsync("container.enc")
|
|
||||||
''' ...
|
|
||||||
''' End Sub
|
|
||||||
''' </example>
|
|
||||||
Public Async Function SaveAsync(Path As String) As Task
|
|
||||||
Try
|
Try
|
||||||
' 1. Serialize
|
_inner = TransformToObject(ReadBytesFromFile(_path))
|
||||||
Dim oFileContainerInner As Byte() = Serialize(_inner)
|
|
||||||
' 2. Compress
|
|
||||||
Dim oFileContainerCompressed As Byte() = Await _compression.CompressAsync(oFileContainerInner)
|
|
||||||
'Dim bFilesCompressed = bFiles
|
|
||||||
' 3. Encrypt
|
|
||||||
Dim oFileContainerEncrypted As Byte() = Await _crypto.EncryptAsync(oFileContainerCompressed)
|
|
||||||
|
|
||||||
BytesToFileAsync(oFileContainerEncrypted, Path)
|
|
||||||
Catch ex As Exception
|
|
||||||
_logger.Error(ex)
|
|
||||||
Throw ex
|
|
||||||
End Try
|
|
||||||
End Function
|
|
||||||
|
|
||||||
''' <summary>
|
|
||||||
''' Lädt einen Datei Container aus dem angegebenen Pfad.
|
|
||||||
''' Anschließend werden die enthaltenen Dateien entschlüsselt, dekomprimiert und in Files abgelegt.
|
|
||||||
''' </summary>
|
|
||||||
''' <param name="Path">Der Pfad mit Dateiname, von dem der Container geladen wird.</param>
|
|
||||||
''' <see cref="Files"/>
|
|
||||||
''' <example>
|
|
||||||
''' container.Load("container.enc")
|
|
||||||
''' Dim files As List(Of FileContainer.FileEntry) = container.Files
|
|
||||||
''' </example>
|
|
||||||
Public Sub Load(Path As String)
|
|
||||||
Try
|
|
||||||
Dim oContainerInnerEncrypted As Byte() = FileToBytes(Path)
|
|
||||||
|
|
||||||
' 1. Decrypt
|
|
||||||
Dim oFileContainerCompressed As Byte() = _crypto.Decrypt(oContainerInnerEncrypted)
|
|
||||||
' 2. Decompress
|
|
||||||
Dim oFileContainerInner As Byte() = _compression.Decompress(oFileContainerCompressed)
|
|
||||||
' 3. Deserialize
|
|
||||||
|
|
||||||
_inner = Deserialize(oFileContainerInner)
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
_logger.Error(ex)
|
_logger.Error(ex)
|
||||||
Throw ex
|
Throw ex
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
''' <summary>
|
Private Function TransformToBytes([Object] As FileContainerInner) As Byte()
|
||||||
''' Lädt einen Datei Container aus dem angegebenen Pfad.
|
Dim oBytes = Serialize([Object])
|
||||||
''' Anschließend werden die enthaltenen Dateien entschlüsselt, dekomprimiert und in Files abgelegt.
|
Dim oCompressed = _compression.Compress(oBytes)
|
||||||
''' </summary>
|
Dim oEncrypted = _crypto.Encrypt(oCompressed)
|
||||||
''' <param name="Path">Der Pfad mit Dateiname, von dem der Container geladen wird.</param>
|
Return oEncrypted
|
||||||
''' <example>
|
|
||||||
''' Public Async Sub foobar()
|
|
||||||
''' ...
|
|
||||||
''' await container.LoadAsync("container.enc")
|
|
||||||
''' Dim files As List(Of FileContainer.FileEntry) = container.Files
|
|
||||||
''' ...
|
|
||||||
''' End Sub
|
|
||||||
''' </example>
|
|
||||||
Public Async Function LoadAsync(Path As String) As Task
|
|
||||||
Try
|
|
||||||
Dim oContainerInnerEncrypted As Byte() = Await FileToBytesAsync(Path)
|
|
||||||
|
|
||||||
' 1. Decrypt
|
|
||||||
Dim oFileContainerCompressed As Byte() = Await _crypto.DecryptAsync(oContainerInnerEncrypted)
|
|
||||||
' 2. Decompress
|
|
||||||
Dim oFileContainerInner As Byte() = Await _compression.DecompressAsync(oFileContainerCompressed)
|
|
||||||
' 3. Deserialize
|
|
||||||
_inner = Deserialize(oFileContainerInner)
|
|
||||||
Catch ex As Exception
|
|
||||||
_logger.Error(ex)
|
|
||||||
Throw ex
|
|
||||||
End Try
|
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
''' <summary>
|
Private Function TransformToObject(Bytes As Byte()) As FileContainerInner
|
||||||
''' Fügt einem Datei Container eine neue Datei hinzu
|
Dim oDecrypted = _crypto.Decrypt(Bytes)
|
||||||
''' </summary>
|
Dim oDecompressed = _compression.Decompress(oDecrypted)
|
||||||
''' <param name="FilePath">Der Pfad zur Datei, die im Container gespeichert werden soll</param>
|
Dim oObject = Deserialize(oDecompressed)
|
||||||
''' <exception cref="FileNotFoundException" />
|
Return oObject
|
||||||
Public Function AddFile(FilePath As String) As String
|
|
||||||
Try
|
|
||||||
Dim oFileInfo As New FileInfo(FilePath)
|
|
||||||
|
|
||||||
If oFileInfo.Exists = False Then
|
|
||||||
Throw New FileNotFoundException($"{FilePath} is not a valid path.")
|
|
||||||
End If
|
|
||||||
|
|
||||||
Return AddFileAsByteArray(IO.File.ReadAllBytes(FilePath))
|
|
||||||
Catch ex As Exception
|
|
||||||
_logger.Error(ex)
|
|
||||||
Throw ex
|
|
||||||
End Try
|
|
||||||
End Function
|
|
||||||
|
|
||||||
Public Function AddFileAsByteArray(FileContents As Byte()) As String
|
|
||||||
Try
|
|
||||||
Dim oFileEntry As New FileEntry With {
|
|
||||||
.Contents = FileContents,
|
|
||||||
.FileId = Guid.NewGuid().ToString()
|
|
||||||
}
|
|
||||||
|
|
||||||
_inner.Files.Add(oFileEntry)
|
|
||||||
|
|
||||||
Return oFileEntry.FileId
|
|
||||||
Catch ex As Exception
|
|
||||||
_logger.Error(ex)
|
|
||||||
Throw ex
|
|
||||||
End Try
|
|
||||||
End Function
|
|
||||||
|
|
||||||
Public Function GetFile(FileId As String) As FileEntry
|
|
||||||
Return _inner.Files.Where(Function(f) f.FileId = FileId).FirstOrDefault()
|
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
Private Function Serialize(InnerData As FileContainerInner) As Byte()
|
Private Function Serialize(InnerData As FileContainerInner) As Byte()
|
||||||
|
Dim oBinaryData As Byte()
|
||||||
|
|
||||||
Using oStream As New MemoryStream
|
Using oStream As New MemoryStream
|
||||||
_formatter.Serialize(oStream, InnerData)
|
Serializer.Serialize(oStream, InnerData)
|
||||||
Return oStream.ToArray()
|
oBinaryData = oStream.ToArray()
|
||||||
End Using
|
End Using
|
||||||
|
|
||||||
|
Return oBinaryData
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
Private Function Deserialize(InnerData As Byte()) As FileContainerInner
|
Private Function Deserialize(InnerData As Byte()) As FileContainerInner
|
||||||
|
Dim oObject As FileContainerInner
|
||||||
|
|
||||||
Using oStream As New MemoryStream(InnerData)
|
Using oStream As New MemoryStream(InnerData)
|
||||||
Dim oInner = TryCast(_formatter.Deserialize(oStream), FileContainerInner)
|
oObject = Serializer.Deserialize(Of FileContainerInner)(oStream)
|
||||||
Return oInner
|
|
||||||
End Using
|
End Using
|
||||||
|
|
||||||
|
Return oObject
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
Private Sub BytesToFile(Data As Byte(), FilePath As String)
|
Private Sub WriteBytesToFile(Data As Byte(), FilePath As String)
|
||||||
Using oSourceStream As New FileStream(FilePath, FileMode.Append, FileAccess.Write, FileShare.None)
|
Using oSourceStream As New FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
|
||||||
oSourceStream.Write(Data, 0, Data.Length)
|
oSourceStream.Write(Data, 0, Data.Length)
|
||||||
oSourceStream.Flush()
|
oSourceStream.Flush()
|
||||||
End Using
|
End Using
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Function FileToBytes(FilePath As String) As Byte()
|
Private Function ReadBytesFromFile(FilePath As String) As Byte()
|
||||||
Return IO.File.ReadAllBytes(FilePath)
|
Using oFileStream = New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096)
|
||||||
End Function
|
|
||||||
|
|
||||||
Private Async Function FileToBytesAsync(FilePath As String) As Task(Of Byte())
|
|
||||||
Using oFileStream = New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, True)
|
|
||||||
Dim oBuffer As Byte() = New Byte(oFileStream.Length - 1) {}
|
Dim oBuffer As Byte() = New Byte(oFileStream.Length - 1) {}
|
||||||
Await oFileStream.ReadAsync(oBuffer, 0, oFileStream.Length)
|
oFileStream.Read(oBuffer, 0, oFileStream.Length)
|
||||||
oFileStream.Close()
|
oFileStream.Close()
|
||||||
Return oBuffer
|
Return oBuffer
|
||||||
End Using
|
End Using
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
Private Async Sub BytesToFileAsync(Data As Byte(), FilePath As String)
|
|
||||||
Using oSourceStream As New FileStream(FilePath, FileMode.Append, FileAccess.Write, FileShare.None, 4096, True)
|
|
||||||
Await oSourceStream.WriteAsync(Data, 0, Data.Length)
|
|
||||||
Await oSourceStream.FlushAsync()
|
|
||||||
End Using
|
|
||||||
End Sub
|
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
22
Filesystem/FileContainerInner.vb
Normal file
22
Filesystem/FileContainerInner.vb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Imports ProtoBuf
|
||||||
|
|
||||||
|
<Serializable>
|
||||||
|
<ProtoContract>
|
||||||
|
Public Class FileContainerInner
|
||||||
|
<ProtoMember(1)>
|
||||||
|
Public FileId As String
|
||||||
|
<ProtoMember(2)>
|
||||||
|
Public Contents As Byte()
|
||||||
|
<ProtoMember(3)>
|
||||||
|
Public CreatedAt As DateTime
|
||||||
|
<ProtoMember(4)>
|
||||||
|
Public UpdatedAt As DateTime
|
||||||
|
<ProtoMember(5)>
|
||||||
|
Public Extension As String
|
||||||
|
|
||||||
|
Public Sub New()
|
||||||
|
FileId = Guid.NewGuid.ToString
|
||||||
|
CreatedAt = Date.Now
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
End Class
|
||||||
@ -47,6 +47,9 @@
|
|||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.5.10\lib\net45\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.5.10\lib\net45\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="protobuf-net, Version=2.4.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\protobuf-net.2.4.0\lib\net40\protobuf-net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Configuration" />
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
@ -73,9 +76,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Compression.vb" />
|
<Compile Include="Compression.vb" />
|
||||||
|
<Compile Include="FileContainer.vb" />
|
||||||
<Compile Include="Encryption.vb" />
|
<Compile Include="Encryption.vb" />
|
||||||
<Compile Include="File.vb" />
|
<Compile Include="File.vb" />
|
||||||
<Compile Include="FileContainer.vb" />
|
<Compile Include="FileContainerInner.vb" />
|
||||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||||
<Compile Include="My Project\Application.Designer.vb">
|
<Compile Include="My Project\Application.Designer.vb">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="NLog" version="4.5.10" targetFramework="net461" />
|
<package id="NLog" version="4.5.10" targetFramework="net461" />
|
||||||
|
<package id="protobuf-net" version="2.4.0" targetFramework="net461" />
|
||||||
</packages>
|
</packages>
|
||||||
Loading…
x
Reference in New Issue
Block a user