Azure-Samples / MqttApplicationSamples

Samples implementing common PubSub patterns for Edge and Cloud Brokers
MIT License
26 stars 25 forks source link

X509Certificate2.CreateFromEncryptedPem works on my local but fails on the server using the same certs #101

Open weirdyang opened 2 months ago

weirdyang commented 2 months ago

Please provide us with the following information:

This issue is for a: (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

Create a client that authenticates with a client cert file, key file and a key file password. Test the client in your local environment, it should work and be able to connect to the server. Deploy the application to a server, it will throw an error at this line despite using the same client cert file, key file and key file password X509Certificate2.CreateFromEncryptedPemFile(certFile, keyFile, keyFilePassword);

Any log messages given by the failure

System.Security.Cryptography.CryptographicException: The EncryptedPrivateKeyInfo structure was decoded but was not successfully interpreted, the password may be incorrect. ---> Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The system cannot find the file specified. at System.Security.Cryptography.CngKeyLite.ImportKeyBlob(String blobType, ReadOnlySpan1 keyBlob, Boolean encrypted, ReadOnlySpan1 password) at System.Security.Cryptography.CngPkcs8.ImportPkcs8(ReadOnlySpan1 keyBlob) at System.Security.Cryptography.CngPkcs8.ImportEncryptedPkcs8PrivateKey(ReadOnlySpan1 password, ReadOnlySpan1 source, Int32& bytesRead) --- End of inner exception stack trace --- at System.Security.Cryptography.CngPkcs8.ImportEncryptedPkcs8PrivateKey(ReadOnlySpan1 password, ReadOnlySpan1 source, Int32& bytesRead) at System.Security.Cryptography.RSAImplementation.RSACng.ImportEncryptedPkcs8PrivateKey(ReadOnlySpan1 password, ReadOnlySpan1 source, Int32& bytesRead) at Internal.Cryptography.PemKeyImportHelpers.ImportEncryptedPem[TPass](ReadOnlySpan1 input, ReadOnlySpan1 password, ImportEncryptedKeyAction1 importAction) at System.Security.Cryptography.RSA.ImportFromEncryptedPem(ReadOnlySpan1 input, ReadOnlySpan1 password) at System.Security.Cryptography.X509Certificates.X509Certificate2.ExtractKeyFromEncryptedPem[TAlg](ReadOnlySpan1 keyPem, ReadOnlySpan1 password, Func1 factory, Func2 import) at System.Security.Cryptography.X509Certificates.X509Certificate2.CreateFromEncryptedPem(ReadOnlySpan1 certPem, ReadOnlySpan1 keyPem, ReadOnlySpan`1 password)

Expected/desired behavior

To be able to use the same set of certs for both environments

Language

C#

OS and Version?

Local: Windows 10 Visual Studio 2019 Deployed: Windows Server 2016 IIS

Mention any other details that might be useful

The fix was to set the application pool identity to Local System, why does this work?


Thanks! We'll be in touch soon.

hansoncaleb commented 5 days ago

I'm experiencing the same issue, with the same Local System "fix". I thought that adding IIS_IUSRS to the file security would help, but it does not. What's interesting is that I know the file is being read successfully based on logging I'm doing.

rido-min commented 5 days ago

I'd suggest filing an issue in https://github.com/dotnet/runtime as this repo does not own the X509Certificate2.CreateFromEncryptedPemFile api.

hansoncaleb commented 5 days ago

I found that IIS doesn't load the user profile for the ApplicationPoolIdentity user. If you set the Load User Profile setting to true in your app pool it will work correctly when using ApplicationPoolIdentity.