2017-09-06 7 views
5

Ich habe eine Xamarin.iOS-Anwendung, die Akavache verwendet, um Daten zwischenzuspeichern und die Anzahl unnötiger Anforderungen an den Server für Daten zu reduzieren. Alles funktioniert gut wie erwartet mit BlobCache.LocalMachine, liebe es.Xamarin.iOS/Akavache - Verschlüsselter Cache mit benutzerdefiniertem EncryptionProvider

Jetzt möchte ich sicherstellen, dass die Daten im Ruhezustand verschlüsselt sind. Bei der Recherche und beim Lesen der Online-Dokumentation habe ich gesehen, dass die Standardimplementierung den Cache unter iOS nicht tatsächlich verschlüsselt und dass ich tatsächlich eine benutzerdefinierte Implementierung von IEncryptionProvider bereitstellen muss.

folgte ich diesen Artikel: http://kent-boogaart.com/blog/password-protected-encryption-provider-for-akavache

Added Eingang aus diesem Thread: https://github.com/akavache/Akavache/issues/190

und endete mit dieser Implementierung bis:

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

Ich registrieren diese Umsetzung wie folgt aus: Locator.CurrentMutable.RegisterConstant(new MyEncryptionProvider(), typeof(IEncryptionProvider)); vor dem Aufruf BlobCache.Secure

Und ich siehe die und DecryptBlock aufgerufen wird, wenn ich .GetOrFetchObject auf diesem sicheren Cache verwenden. So weit, ist es gut.

Das Problem, das ich in laufen, ist, dass es nicht bei dem Versuch, mit diesem Fehler Deserialize von Newtonsoft:

{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] 

Wenn das gleiche Objekt zwischengespeichert wird mit der BlobCache.LocalMachine die gleiche Struktur Daten erfolgreich wie folgt gespeichert wird:

[ 
    { 
    "Name": "John Smith", 
    "Date": "2017-04-03T20:00:00-04:00", 
    "Number1": -8820768.6192349959, 
    "Number2": -25540081.8275, 
    "Number3": -0.0045255076670528034, 
    "Number4": 0.0457761358483606, 
    "RelatedObjects": [], 
    "LastUpdateTime": "2017-04-04T17:36:06.247-04:00" 
    } 
] 

Was fehlt mir hier? Sehr frustriert, ich hoffe wirklich, dass jemand etwas sieht, was ich nicht bin. Danke für Ihre Hilfe.

+1

Referenzieren Sie einfach das andere Problem mit der Probe für den Fall, dass jemand hier zuerst kommt https://StackOverflow.com/Questions/46104014/xamarin-Iso-akavache-Working-Beispiel –

+0

Mit Hilfe des Beispiels in diesem Beitrag: https://stackoverflow.com/questions/46104014/xamarin-ios-akavache-wo Rking-Beispiel Ich konnte dieses Problem gelöst und ein funktionierendes Beispiel wird in der Beispiellösung hier gezeigt: https://github.com/dmitrysamuylov/xamarin-ios-akavache-secure-beispiel hoffe, es hilft jemandem –

Antwort

Verwandte Themen