From f1cfe0da6a707b573a7686bfe51a0175b6e3a5f5 Mon Sep 17 00:00:00 2001 From: Oscar Iong Date: Sat, 8 Jan 2022 09:56:03 +0800 Subject: [PATCH 1/2] Implement CryptoSerializable payload --- src/FileCache/FileCache.cs | 7 +++- src/FileCache/FileCacheManager.cs | 70 +++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/FileCache/FileCache.cs b/src/FileCache/FileCache.cs index 1212e09..a26603f 100644 --- a/src/FileCache/FileCache.cs +++ b/src/FileCache/FileCache.cs @@ -81,7 +81,11 @@ public enum PayloadMode /// /// Treat the paylad as raw bytes. A byte[] and readable streams are supported on add. /// - RawBytes + RawBytes, + /// + /// Treat the payload as a crypto serializable object. + /// + CryptoSerializable, } /// @@ -337,6 +341,7 @@ private void Init( CacheManager.PolicySubFolder = _policySubFolder; CacheManager.Binder = _binder; CacheManager.AccessTimeout = new TimeSpan(); + //CacheManager.CryptoKey = cryptoKey; //check to see if cache is in need of immediate cleaning if (ShouldClean()) diff --git a/src/FileCache/FileCacheManager.cs b/src/FileCache/FileCacheManager.cs index b9515fd..c7c24f3 100644 --- a/src/FileCache/FileCacheManager.cs +++ b/src/FileCache/FileCacheManager.cs @@ -5,6 +5,7 @@ using System.Reflection; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; +using System.Security.Cryptography; using System.Text; using System.Threading; @@ -21,6 +22,7 @@ public abstract class FileCacheManager public string CacheSubFolder { get; set; } public string PolicySubFolder { get; set; } public SerializationBinder Binder { get; set; } + public string CryptoKey { get; set; } /// /// Used to determine how long the FileCache will wait for a file to become @@ -151,6 +153,9 @@ public virtual FileCachePayload ReadFile(FileCache.PayloadMode mode, string key, case FileCache.PayloadMode.RawBytes: payload.Payload = LoadRawPayloadData(cachePath); break; + case FileCache.PayloadMode.CryptoSerializable: + payload.Payload = DeserializeCrypto(cachePath); + break; default: throw new ArgumentOutOfRangeException(nameof(mode), mode, null); } @@ -222,6 +227,54 @@ protected virtual object Deserialize(string fileName, SerializationBinder object } return data; } + protected virtual object DeserializeCrypto(string fileName, SerializationBinder objectBinder = null) + { + object data = null; + if (File.Exists(fileName)) + { + AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); + MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); + SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider(); + byte[] aeskey = sha256.ComputeHash(Encoding.UTF8.GetBytes(CryptoKey)); + byte[] aesiv = md5.ComputeHash(Encoding.UTF8.GetBytes(CryptoKey)); + aes.Key = aeskey; + aes.IV = aesiv; + + using (FileStream stream = GetStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + using (Stream cryptoStream = new CryptoStream(stream, aes.CreateDecryptor(), CryptoStreamMode.Read)) + { + BinaryFormatter formatter = new BinaryFormatter(); + + //AC: From http://spazzarama.com//2009/06/25/binary-deserialize-unable-to-find-assembly/ + // Needed to deserialize custom objects + if (objectBinder != null) + { + //take supplied binder over default binder + formatter.Binder = objectBinder; + } + else if (Binder != null) + { + formatter.Binder = Binder; + } + try + { + data = formatter.Deserialize(cryptoStream); + } + catch (SerializationException) + { + data = null; + } + finally + { + cryptoStream.Close(); + stream.Close(); + } + } + } + } + return data; + } /// /// This function serves to centralize file writes within this class @@ -276,6 +329,23 @@ public virtual long WriteFile(FileCache.PayloadMode mode, string key, FileCacheP case FileCache.PayloadMode.Filename: File.Copy((string)data.Payload, cachedItemPath, true); break; + case FileCache.PayloadMode.CryptoSerializable: + AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); + MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); + SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider(); + byte[] aeskey = sha256.ComputeHash(Encoding.UTF8.GetBytes(CryptoKey)); + byte[] aesiv = md5.ComputeHash(Encoding.UTF8.GetBytes(CryptoKey)); + aes.Key = aeskey; + aes.IV = aesiv; + using (FileStream stream = GetStream(cachedItemPath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + using (CryptoStream cryptoStream = new CryptoStream(stream, aes.CreateEncryptor(), CryptoStreamMode.Write)) + { + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(cryptoStream, data.Payload); + } + } + break; } //adjust cache size (while we have the file to ourselves) From 94f6e18e392463abc567a21f778adea958488087 Mon Sep 17 00:00:00 2001 From: Oscar Iong Date: Sat, 8 Jan 2022 10:05:22 +0800 Subject: [PATCH 2/2] remove commant out line --- src/FileCache/FileCache.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/FileCache/FileCache.cs b/src/FileCache/FileCache.cs index a26603f..cbff5f6 100644 --- a/src/FileCache/FileCache.cs +++ b/src/FileCache/FileCache.cs @@ -341,7 +341,6 @@ private void Init( CacheManager.PolicySubFolder = _policySubFolder; CacheManager.Binder = _binder; CacheManager.AccessTimeout = new TimeSpan(); - //CacheManager.CryptoKey = cryptoKey; //check to see if cache is in need of immediate cleaning if (ShouldClean())