2

I am trying to host a ASP.NET Core 2 web application using Azure's Web App Service. The web app runs fine on my development machine (Windows 10). It also works on a Ubuntu 17.10 virtual machine when I publish the files. However, when I publish the web app from Visual Studio to Azure I get the following error message:

WindowsCryptographicException: The system cannot find the file specified
    System.Security.Cryptography.CngKey.Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
    System.Security.Cryptography.CngKey.Open(string keyName, CngProvider provider)
    Internal.Cryptography.Pal.CertificatePal.GetPrivateKey<T>(Func<CspParameters, T> createCsp, Func<CngKey, T> createCng)
    Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
    Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey<T>(X509Certificate2 certificate, Predicate<X509Certificate2> matchesConstraints)
    ...
    Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
    Microsoft.AspNetCore.Server.IISIntegration.IISSetupFilter+<>c__DisplayClass3_0.<Configure>b__0(IApplicationBuilder app)
    Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter+<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder)
    Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
.NET Core 4.6.26212.01 X86 v4.0.0.0    |   Microsoft.AspNetCore.Hosting version 2.0.2-rtm-10011    |    Microsoft Windows 10.0.14393

I am storing a key file in the project directory and attempting to create credentials from it.

After searching, I have found the following sites that point to similar solutions: https://github.com/dotnet/corefx/issues/11042, https://github.com/IdentityServer/IdentityServer4/issues/1432, Certificate not found when deploying IdentityServer 4 to Azure VM, and CryptographicException was unhandled: System cannot find the specified file

These suggest that I need to modify the settings of the Application Pool and set the "Load User Profile" to true and properly set the permissions of the file. However, I am unsure of how to do this using the Azure Portal.

In addition, instead of modifying a file on the server, is there a solution where code can be added to either Program.cs or Startup.cs (excerpts given below)?

Program.cs (referenced link)

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseSetting("detailedErrors", "true")
            .UseIISIntegration()
            .UseStartup<Startup>()
            .CaptureStartupErrors(true)
            .Build();
}

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {   
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
        }
        app.UseStaticFiles();
        app.UseMvc();
    }
}

Thanks in advance.

Update #1

The app deploys properly. I just encounter the error when the following code is executed.

private static RSA GetPrivateKey(byte[] p12) {
    var certificate = new X509Certificate2(p12, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
    var rsa = certificate.GetRSAPrivateKey();
    return rsa;
}

Here is my project .csproj file:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp2.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="GDataDB" Version="1.0.0" />
        <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.8" />
        <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.3" />
    </ItemGroup>
    <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
    </ItemGroup>
    <ItemGroup>
        <Folder Include="Pages\" />
        <Folder Include="Properties\PublishProfiles\" />
    </ItemGroup>
    <ItemGroup>
        <None Update="total-method-203123-88f147135d99.p12">
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </None>
    </ItemGroup>
</Project>

Udpate #2

Here is a minimal repo that demonstrates the error: https://github.com/jonliew/testdatawebapp

I first publish the GDataDB to a nuget package using the FolderProfile in Visual Studio. Then, I add the package to the DataWebApp project. Finally, I publish the DataWebApp and get the above behavior.

jonliew
  • 21
  • 3
  • take a look at this: https://stackoverflow.com/a/27146917/1831108 – watashiSHUN May 14 '18 at 18:47
  • I tried setting the X509KeyStorageFlags to no avail. The other solutions suggest that I need to load the user profile, which I am unsure about. – jonliew May 16 '18 at 03:49

1 Answers1

0

Most likely, the issue is that you are targeting .NET Core 2.0.8, which is not yet fully deployed on App Service. See here for the announcement.

To verify whether this is indeed the problem, please try deploying to a test Web App in the West US 2 region (not West US), which does have the release. You should not get the error there.

David Ebbo
  • 42,443
  • 8
  • 103
  • 117
  • I believe that I am targeting .NET Core 2.0.7, since that is the version of Microsoft.AspNetCore.All my project is using. I tried to deploy to the West US 2 region in a new resource group and I got the same error. The app deploys properly; it only encounters the error when the following code is executed: private static RSA GetPrivateKey(byte[] p12) { var certificate = new X509Certificate2(p12, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable); var rsa = certificate.GetRSAPrivateKey(); return rsa; } – jonliew May 13 '18 at 04:15
  • That's odd. As a test, does it work in West US 2 if you instead target 2.0.8? – David Ebbo May 13 '18 at 04:17
  • I made an edit to my above comment after you replied. If updating the Microsoft.AspNetCore.All nuget package to 2.0.8 targets .NET Core 2.0.8, then deploying a 2.0.8 to West US 2 does not help. I included both the code in my above comment and my .csproj in Update #1. – jonliew May 13 '18 at 05:00
  • Can you please [share a minimal repo](https://github.com/projectkudu/kudu/wiki/Using-a-git-repo-to-report-an-issue) the demonstrates the issue? It will help us investigate. Thanks. – David Ebbo May 14 '18 at 14:26
  • Here is a link to a minimal repo: https://github.com/jonliew/testdatawebapp My update in the original post describes how I build it. – jonliew May 16 '18 at 03:34
  • 1
    Just noticed your comment about user profile. Try setting `WEBSITE_LOAD_USER_PROFILE=1` in the App Settings in the Portal. See [here](https://github.com/projectkudu/kudu/wiki/Configurable-settings#add-user-profile-support-for-a-site) for more info. – David Ebbo May 16 '18 at 03:50
  • Unfortunately, I am operating on the Free tier so this setting is not available. I managed to get my web app running on Heroku using Docker. – jonliew May 16 '18 at 08:55