11
var rawData = Convert.FromBase64String(_signingKey);
var cng = CngKey.Import(rawData, CngKeyBlobFormat.Pkcs8PrivateBlob);

I use this code to extract key, from embedded base64 string. It works fine when I test it locally but when I publish on azure I get following exception:

WindowsCryptographicException: The system cannot find the file specified

(once again I'm not reading from any file) I need this to communicate with apple apns for push notifications, is there any workaround? And this happens only on free service plan, if I switch to basic plan it's working.

Vladimir Sakic
  • 111
  • 1
  • 5
  • Perhaps this is related "One of things that comes to my mind is the identity of your app pool, make sure that the Load user profile is turned on otherwise the crypto susbsystem does not work." [http://stackoverflow.com/questions/14263457/x509-certificate-not-loading-private-key-file-on-server](http://stackoverflow.com/questions/14263457/x509-certificate-not-loading-private-key-file-on-server) – skjelland Jan 11 '17 at 14:24
  • @Vladimir did you ever find a solution to this issue? – lehn0058 Apr 11 '17 at 18:55
  • @lehn0058 - See strohmsn's answer below (was posted a week before you posted above comment). – Nicholas Petersen Apr 26 '18 at 07:37

6 Answers6

14

I ran into the same error after publishing an existing application to Azure. In my case the problem was solved after I set WEBSITE_LOAD_USER_PROFILE = 1 in App Services / App Name / Application Settings.

strohmsn
  • 141
  • 1
  • 4
  • THAT worked, can't believe it. Didn't even have to restart the app (though maybe just saving settings did that). You sir, were very kind to put this information here, who knows how much pain could have come about by not having this little answer. – Nicholas Petersen Apr 26 '18 at 07:34
  • @Alexander sorry to hear that. I actually had this problem pop up just again yesterday, republished an app needing this to a different app and forgot to set this setting, it threw me for a while (I had been expecting another dll type problem for other reasons), but then remembered to just set this setting, and immediately fixed it. Is the error you’re seeing identical? – Nicholas Petersen May 31 '18 at 19:00
  • @NicholasPetersen I think. ```Application: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The system cannot find the file specified Application: at System.Security.Cryptography.CngKey.Import(Byte[] keyBlob, String curveName, CngKeyBlobFormat format, CngProvider provider)``` – Alexander May 31 '18 at 20:09
  • 1
    @NicholasPetersen It's [this](https://stackoverflow.com/questions/43349954/how-can-i-sign-a-jwt-token-on-an-azure-webjob-without-getting-a-cryptographicexc)... I haven't found any way to not store the imported key – Alexander May 31 '18 at 20:50
2

Setting WEBSITE_LOAD_USER_PROFILE to equal 1 in the Azure App Service configuration definitely got my remote iOS notifications working. Using dotAPNS for C# .NET I also needed to omit apns.UseSandbox().

1

It seems that it causes by there is no certificate attached in your Azure Mobile App. If it is that case, we need to upload the "Development" or "Distribution" SSL certificate to the WebApp. More info about how to send push notifications to iOS App, please refer to the azure document.

enter image description here

Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • But I'm not using any azure service for notifications, I'm using apple's http/2 endpoint and I wrote custom code for sending notifications, and it's working when I test it localy – Vladimir Sakic Dec 16 '16 at 18:15
1

I've had a similar error trying to construct a X509Certificate2 from a byte array - worked fine locally but once I deploy to Azure Web App, I got the same and VERY misleading file not found exception.

The real issue turned out to be that there was no user store associated with the web service account. You can also get a similar error if there are permission-related errors with accessing the certificate store on Windows.

In any case - In my scenario I fixed the problem by using MachineKeySet: new X509Certificate2(certRawBytes, default(string), X509KeyStorageFlags.MachineKeySet);

So, in your scenario, try something like:

var keyParams = new CngKeyCreationParameters
{
  KeyCreationOptions = CngKeyCreationOptions.MachineKey,
};
CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams);

Note: You may have to set a few parameters to get the above working. The Import method doesn't seem to support MachineKey - but you should be able to achieve similar outcome by using the Create method.

Adriaan de Beer
  • 1,136
  • 13
  • 23
1

To add to @strohmsn's answer, you can also set the App Service settings with this value directly within Visual Studio on the Publish page for web apps: Right click on web app and select Publish, then select App Service Settings, and you can add setting properties there: WEBSITE_LOAD_USER_PROFILE = 1 in this case. See screenshot:

enter image description here

Nicholas Petersen
  • 9,104
  • 7
  • 59
  • 69
0

For making it works, I needed TWO things in AzureWebApp..

So my code is :

//I load the PrivateKey here
ReadedByte = System.IO.File.ReadAllBytes(strPathPrivateKey);
//create the RSA thing
RSA rsa = System.Security.Cryptography.RSA.Create();
//import the key.  It crashed HERE with the 'System cannot find file specified'
rsa.ImportPkcs8PrivateKey(source: ReadedByte,bytesRead: out int _);  

It works perfectly locally. But, to make it WORK on Azure Web App, I had to have those TWO requirements :

1 - the WEBSITE_LOAD_USER_PROFILE = 1 spoken in the discussion above and below

2 - The App Service Plan must include "Custom domains / SSL" !

  • ...so No 'F1 Share Infrastructure' nor 'D1 Share Infrastructure'. The lowest Service plan that worked for me was 'B1 - 100 Total Acu'.

Maybe I have something wrong somewhere else in my code, or my 'RSA' choice is bad..anyway...

It now works!

Simon
  • 2,266
  • 1
  • 22
  • 24