Akavache
Akavache copied to clipboard
EncryptionProvider is not protecting data under monodroid, monotouch, or monomac
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.
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.
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
Any update on the data encryption on iOS/Android ? Would be really appreciated :) Thanks !
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!
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.
I think that PCLCrypto could help as @KarinBerg said. Can we implement our own CustomEncryptionProvider and force Akavache to register it on IEncryptionProvider ?
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 :) !!!
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?
Stop using the static? It's only there for convenience. Inject the interface implementation into your services then you can unit tests.
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;
I had issue with following Kents blog, because I am using PCL's. Incase someone needs help, you can follow this blog post:
Hi @cfl777, the blog post link you provided seems to an expired website. Can you please help with another link?
@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
Akavache is a great library for handling your caching needs. Have used it successfully in Xamarin applications, however there is a problem…
Thanks @cfl777