We just got another email asking how Crypteron's CipherDB encryption works with Entity Framework's projections. So I decided it's time to write a blog post about it.
For starters, Crypteron works very well with Entity Framework. And for the most past Entity Framework works with - well - Entities. But there are some cases where one may use projections that result in non-Entity classes.
What are projections?
In the simplest words, a projection is when the Entity class is 'projected' into another class or an anonymous class. This is typically done when your entity may have a very large number of properties (i.e. very wide row) but you need only a few properties. For example: Select(product => new { product.price })
. This will project only the price of the entity into an anonymous object and that's the return type (not the entity). Note that in most cases Entity Framework will deliver Entities - so you're all good. This is for advanced use cases.
Problem?
The issue is the return type is simple an anonymous object and is technically not an Entity. So Entity Framework doesn't trigger Crypteron's CipherDB agent and is therefore still in an encrypted state.
Solution?
The solutions are simple. Either use entities and everything is back to normal. Or if you must use projection, use Crypteron CipherObject - our object encryption agent - to decrypt the object. This is because we've designed all Crypteron agent's to be cross-compatible with each other. So for example, data encrypted by a Java CipherObject agent - perhaps a large Apache Spark cluster - can be blindly copied into SQL storage use with the C# CipherDB agent. The only requirement is that these agent's use the same AppSecret so they are considered part of the same suite that pools or share their protected data. Crypteron's cross-compatibility enables many such powerful scenarios and projections here are just another example.
Show me the code
The solution is to use CipherObject.Protector.Unseal(projectedObject)
on the projected object. A full code example will make this clear. We'll use the Crypteron sample apps on GitHub for a reference so you can try yourself. Install the Crypteron CipherObject NuGet package. Then put the code below in the Test() method within ProcessCustomer.cs. Run it and choose "t" at the menu.
// We define a concrete class for our projection and decorate it with // the [Secure] attribute public class ProjectedUser { [Secure] public string Name { get; set; } [Secure] public string CreditCard { get; set; } [Secure] public byte[] SSN { get; set; } public string OrderItem { get; set; } } public void Test() { // Placeholder for anything you want ... using (var secDb = new SecDbContext()) { // This will work ... foreach (var o in secDb.Users.Take(5).Select(u => new ProjectedUser() { Name = u.CustomerName, CreditCard = u.SecureSearch_CreditCardNumber, SSN = u.Secure_SocialSecurityNumber, OrderItem = u.OrderItem })) { // ... because of CipherObject CipherObject.Protector.Unseal(o); // <=== // do some work } // This will NOT work, they're just anonymous objects // NOT entities foreach (var o in secDb.Users.Take(5).Select(u => new { u.CustomerName, u.SecureSearch_CreditCardNumber, u.Secure_SocialSecurityNumber, u.OrderItem })) { // do some work } } }
Conclusion
That's it! That's how you can get projections working with Entity Framework. In fact, with CipherObject, you have tremendous flexibility and power to architect a wide variety of solution. If you have any question or need some guidance, please feel free to drop us a line at support@crypteron.com. We look forward to hearing from you.