데이터를 캐시하고 데이터 서버의 불필요한 요청 수를 줄이기 위해 Akavache를 사용하는 Xamarin.iOS 앱이 있습니다. 모든 것이 예상대로 잘 작동합니다. BlobCache.LocalMachine
을 사용하십시오.Xamarin.iOS/Akavache - 사용자 정의 EncryptionProvider를 사용한 암호화 된 캐시
이제 데이터가 암호화되어 있는지 확인하고 싶습니다. 이 문제를 조사하고 온라인에서 설명서를 읽으면서 기본 구현은 실제로 iOS의 캐시를 암호화하지 않고 실제로 IEncryptionProvider
의 맞춤 구현을 제공해야한다는 것을 알았습니다. http://kent-boogaart.com/blog/password-protected-encryption-provider-for-akavache
추가 입력 :
나는이 기사 다음 https://github.com/akavache/Akavache/issues/190을 그리고이 구현 결국 :
public interface IPasswordProtectedEncryptionProvider : IEncryptionProvider
{
void SetPassword(string password);
}
public sealed class MyEncryptionProvider : IPasswordProtectedEncryptionProvider
{
static readonly byte[] salt = Encoding.ASCII.GetBytes("dVBZMQWyFRcJOIas");
readonly IScheduler scheduler;
readonly SymmetricAlgorithm symmetricAlgorithm;
ICryptoTransform decryptTransform;
ICryptoTransform encryptTransform;
public MyEncryptionProvider()
{
scheduler = BlobCache.TaskpoolScheduler ?? throw new ArgumentNullException(nameof(scheduler), "Scheduler instance is null");
symmetricAlgorithm = new RijndaelManaged();
var securePassword = "kadhaskdhsakhaskjdhaskjdhaskdjashdkjahkfghkjhew";
SetPassword(securePassword);
}
public void SetPassword(string password)
{
if(password == null)
throw new ArgumentNullException(nameof(password), "password can't be null");
var derived = new Rfc2898DeriveBytes(password, salt);
var bytesForKey = symmetricAlgorithm.KeySize/8;
var bytesForIV = symmetricAlgorithm.BlockSize/8;
symmetricAlgorithm.Key = derived.GetBytes(bytesForKey);
symmetricAlgorithm.IV = derived.GetBytes(bytesForIV);
decryptTransform = symmetricAlgorithm.CreateDecryptor(symmetricAlgorithm.Key, symmetricAlgorithm.IV);
encryptTransform = symmetricAlgorithm.CreateEncryptor(symmetricAlgorithm.Key, symmetricAlgorithm.IV);
}
public IObservable<byte[]> DecryptBlock(byte[] block)
{
if (block == null)
{
throw new ArgumentNullException(nameof(block), "block can't be null");
}
if (decryptTransform == null)
{
return Observable.Throw<byte[]>(new InvalidOperationException("You must call SetPassword first."));
}
return Observable.Start(() => InMemoryTransform(block, decryptTransform), scheduler);
}
public IObservable<byte[]> EncryptBlock(byte[] block)
{
if (block == null)
{
throw new ArgumentNullException(nameof(block), "block can't be null");
}
if (encryptTransform == null)
{
return Observable.Throw<byte[]>(new InvalidOperationException("You must call SetPassword first."));
}
return Observable.Start(() => InMemoryTransform(block, encryptTransform), scheduler);
}
static byte[] InMemoryTransform(byte[] bytesToTransform, ICryptoTransform transform)
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
{
cryptoStream.Write(bytesToTransform, 0, bytesToTransform.Length);
}
return memoryStream.ToArray();
}
}
}
내가 같이이 구현 등록 : Locator.CurrentMutable.RegisterConstant(new MyEncryptionProvider(), typeof(IEncryptionProvider));
호출하기 전에 BlobCache.Secure
해당 보안 캐시에서 .GetOrFetchObject
을 사용할 때 EncryptBlock
및 DecryptBlock
이 호출됩니다. 여태까지는 그런대로 잘됐다. 동일한 개체가 성공적으로 다음과 같이 저장되어있는 BlobCache.LocalMachine
동일한 데이터 구조를 사용하여 캐시되면
{Newtonsoft.Json.JsonReaderException: Read past end of current container context. Path ''.
at Newtonsoft.Json.Bson.BsonReader.ReadNormal() [0x0013c] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Bson.BsonReader.Read() [0x00033] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonReader.ReadAndAssert() [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x000b6] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x0006d] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00053] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.Deserialize[T] (Newtonsoft.Json.JsonReader reader) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at Akavache.Sqlite3.SQLitePersistentBlobCache.DeserializeObject[T] (System.Byte[] data) [0x00074] in <67aced6c5c1a4c15b03e120d7300429d>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.12.0.20/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:151
at System.Reactive.PlatformServices.ExceptionServicesImpl.Rethrow (System.Exception exception) [0x00006] in <427ee2007f4d40bb9d3f1fcd73e9b750>:0
at System.Reactive.ExceptionHelpers.ThrowIfNotNull (System.Exception exception) [0x0000d] in <ab76b1b1678341d69f8fc2c1f68d0bf5>:0
at System.Reactive.Subjects.AsyncSubject`1[T].GetResult() [0x00039]
을 :
내가으로 실행하는 문제는 Newtonsoft
이 오류로 역 직렬화하려고 할 때 실패한다는 것입니다
무엇이 여기에 있습니까? 매우 좌절하고, 누군가가 내가 아닌 것을보기를 정말로 바란다. 당신의 도움을 주셔서 감사합니다. 이 게시물의 예제의 도움으로
누군가가 여기에 도착한 경우를 대비하여 샘플과 함께 다른 문제를 참조하십시오. https://stackoverflow.com/questions/46104014/xamarin-ios-akavache-working-example –
이 게시물의 예제를 사용하여 다음을 수행하십시오. https://stackoverflow.com/questions/46104014/xamarin-ios-akavache-wo rking-example 이 문제를 해결할 수 있었고 작업 예제가 샘플 솔루션에 표시되었습니다. https://github.com/dmitrysamuylov/xamarin-ios-akavache-secure-example –