reactiveui / Akavache

An asynchronous, persistent key-value store created for writing desktop and mobile applications, based on SQLite3. Akavache is great for both storing important data as well as cached local data that expires.
https://evolve.xamarin.com/session/56e2044afd00c0253cae33a3
MIT License
2.45k stars 288 forks source link

EncryptionProvider is not protecting data under monodroid, monotouch, or monomac #190

Open roberleitner opened 9 years ago

roberleitner commented 9 years ago

SQLiteEncryptedBlobCache uses Akavache.EncryptionProvider for encryption. EncryptionProvider in turn uses static references to ProtoctedData for encrypting data during reads/writes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Akavache
{
    public class EncryptionProvider : IEncryptionProvider
    {
        public IObservable<byte[]> EncryptBlock(byte[] block)
        {
            return Observable.Return(ProtectedData.Protect(block, null, DataProtectionScope.CurrentUser));
        }

        public IObservable<byte[]> DecryptBlock(byte[] block)
        {
            return Observable.Return(ProtectedData.Unprotect(block, null, DataProtectionScope.CurrentUser));
        }
    }
}

EncryptionProvider has references to System.Security.Cryptography but ProtectedData doesn't exist in monotouch or monodroid. On both those platforms, Akavache falls back to the built in Akavache.ProtectedData shim which provides no encryption.

namespace Akavache
{
    public static class ProtectedData
    {
        public static byte[] Protect(byte[] originalData, byte[] entropy, DataProtectionScope scope = DataProtectionScope.CurrentUser)
        {
            return originalData;
        }

        public static byte[] Unprotect(byte[] originalData, byte[] entropy, DataProtectionScope scope = DataProtectionScope.CurrentUser)
        {
            return originalData;
        }
    }

    public enum DataProtectionScope {
        CurrentUser,
    }
}

BlobCache.Secure (SQLiteEncryptedBlobCache) is affected by this as is anything else that uses the EncryptionProvider under monotouch or monodroid.

roberleitner commented 9 years ago

Further investigation shows that any project which includes the ProtectDataShim.cs file will not encrypt data.

I would think that rather than just returning the original data this class should throw a NotImplementedException so consumers would know that encryption isn't supported on those platforms.

anaisbetts commented 9 years ago

Nope, we just need to Fix The Bug, and since we already have a bunch of unencrypted databases out there, we also need to create a migration that will do a table copy to encrypt data that isn't encrypted

cyrilcathala commented 9 years ago

Any update on the data encryption on iOS/Android ? Would be really appreciated :) Thanks !

flagbug commented 8 years ago

The problem with this is, that Android and iOS don't have support for the ProtectedData class, so we don't have any way of encrypting the data. If anyone knows of a cross-platform way to do this, let me know!

KarinBerg commented 8 years ago

Maybe this library could help? https://github.com/aarnott/pclcrypto

It was mentioned in a Xamarin Evolve16 talk: https://youtu.be/rCT9kiA7SE0 I'm no expert but maybe it helps.

AntM90 commented 8 years ago

I think that PCLCrypto could help as @KarinBerg said. Can we implement our own CustomEncryptionProvider and force Akavache to register it on IEncryptionProvider ?

KarinBerg commented 7 years ago

This is for everyone who can't wait for the Akavache release to fix this. The following article explains how you can do the encryption by yourself to work on both iOS and Android. http://kent-boogaart.com/blog/password-protected-encryption-provider-for-akavache

Hint: also read the comments on the article :) !!!

KarinBerg commented 7 years ago

Hey guys, I tried to implement and register my own IEncryptionProvider but Akavache is ignoring it. I register my implememation by calling Locator.CurrentMutable.RegisterConstant(new MyEncryptionProvider(), typeof(IEncryptionProvider)); But BlobCache.Secure is always using its own implementation.

Can someone give my a hint?

ghuntley commented 7 years ago

Stop using the static? It's only there for convenience. Inject the interface implementation into your services then you can unit tests.

KarinBerg commented 7 years ago

Hi Geoffrey, thanks for the hint. I took a while to understand my mistake. But now I discovered it. The problem was that BlobCache.Secure was my first call on the static class BlobCache. This triggered the static initializer from the BlobCache class which initialized the Locator stuff.

static BlobCache()
{
    Locator.RegisterResolverCallbackChanged(() => 
    {
          if (Locator.CurrentMutable == null) return;
              Locator.CurrentMutable.InitializeAkavache();
    });

    InMemory = new InMemoryBlobCache(Scheduler.Default);
}

So my registration for the IEncryptionProvider had no effect. :)

Now I do the following which works:

// This triggers the static initializer from above
BlobCache.ApplicationName = "FleetBoard App Framework"; 
// Now register my own IEncryptionProvider
Locator.CurrentMutable.RegisterConstant(new MyEncryptionProvider(), typeof(IEncryptionProvider));
// Now get an instance of ISecureBlobCache by the Locator directly
Locator.CurrentMutable.GetService<ISecureBlobCache>(); 
// or by static property
BlobCache.Secure;
cfl777 commented 7 years ago

I had issue with following Kents blog, because I am using PCL's. Incase someone needs help, you can follow this blog post:

akema-trebla commented 6 years ago

Hi @cfl777, the blog post link you provided seems to an expired website. Can you please help with another link?

cfl777 commented 5 years ago

@akema-trebla Sorry didn't see your query until now: Please find corrected link here:

https://medium.com/@casseykeating/securing-akavache-cache-for-xamarin-966641de3c2b

Medium
Securing Akavache cache for Xamarin – Cassey Keating – Medium
Akavache is a great library for handling your caching needs. Have used it successfully in Xamarin applications, however there is a problem…
akema-trebla commented 5 years ago

Thanks @cfl777