Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Protection using Entity Framework Core

So I have followed microsoft's official guide (https://learn.microsoft.com/el-gr/aspnet/core/security/data-protection/implementation/key-storage-providers?view=aspnetcore-2.2&tabs=visual-studio) for encrypting data and storing them in database using Entity Framework Core, but I can't make it work accross multiple machines. So I used Entity Framework Core implementation because in the guide says "With this package, keys can be shared across multiple instances of a web app.". The app works perfectly when using it from the deployed version for example xyz.com, but It doesn't let me interfere from localhost. Will it be a problem afterwards when my virtual machine is maxed out and I want to add another one? If so how can I make it work in both the deployed site and different machines? There is no tutorial which implements that, I have searched everywhere. Thank you very much.

services.AddDataProtection()
                .UseCryptographicAlgorithms(
                    new AuthenticatedEncryptorConfiguration()
                    {
                        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
                        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256,

                    }
                ).PersistKeysToDbContext<DataContext>();

Update 12-6-2019

So I followed microsoft's documentation (https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-encryption-at-rest?view=aspnetcore-2.2) and it states:

"If the app is spread across multiple machines, it may be convenient to distribute a shared X.509 certificate across the machines and configure the hosted apps to use the certificate for encryption of keys at rest"

I generated a x.509 certificate using this tutorial:

(https://www.youtube.com/watch?v=1xtBkukWiek)

My updated code:

        services.AddDataProtection()
                .UseCryptographicAlgorithms(
                    new AuthenticatedEncryptorConfiguration()
                    {
                        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
                        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256,

                    }
                )
                // )
                .ProtectKeysWithCertificate(new X509Certificate2("wibit-test-cert.pfx", "password"))
                .PersistKeysToDbContext<DataContext>();

When testing on my local machine it works fine, but when I deploy it, I get this error:

error: "The system cannot find the file specified"

I have tried several ways to fix it including _hostingEnvironment.ContentRootPath or WebRootPath. Both these ways and the one I use in the updated code work in my machine but not in the deployed app.

Any clues?

like image 439
flyingpig Avatar asked Jun 11 '19 04:06

flyingpig


1 Answers

I finally fixed it! The problem was that I didn't set the application name:

.SetApplicationName("myapp")

And I changed the path of the certificate to this:

.ProtectKeysWithCertificate(new X509Certificate2(Path.Combine(_hostingEnvironment.ContentRootPath,"wibit-test-cert.pfx"), "password"))

Also it may be a permission problem, because when I hosted the app in A2Hosting it could't find the file specified(wibit-test-cert.pfx), but when I deployed in GCP Cloud it worked!

Now I can encrypt and decrypt data using the same database with different apps.

So my final code is this:

services.AddDataProtection()
  .UseCryptographicAlgorithms(
      new AuthenticatedEncryptorConfiguration()
         {
             EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
             ValidationAlgorithm = ValidationAlgorithm.HMACSHA256,

          }
       )
       .SetApplicationName("myapp")
       .ProtectKeysWithCertificate(new X509Certificate2(Path.Combine(_hostingEnvironment.ContentRootPath,"wibit-test-cert.pfx"), "password"))
       .PersistKeysToDbContext<DataContext>();
like image 85
flyingpig Avatar answered Nov 02 '22 02:11

flyingpig