Search code examples
asp.net-core-webapiasp.net-core-2.2ef-core-2.2

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?


Solution

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