"Key not valid for use in specified state" - happens in .Net Framework 4.7.2 only, not on .Net Core 2.2
See original GitHub issueWhich Version of MSAL are you using ? Microsoft.Identity.Client Version=3.0.8
Platform
my library in .Net Core and a web job console in .Net Framework 4.7.2
What authentication flow has the issue?
- Desktop / Mobile
- Interactive
- Integrated Windows Auth
- Username Password
- Device code flow (browserless)
- Web App
- Authorization code
- OBO
- Web API
- OBO
Other? - please describe;
Is this a new or existing app?
C. This is a new app or experiment
Repro
SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder();
connectionStringBuilder.DataSource = this.Settings.DataSource;
connectionStringBuilder.InitialCatalog = this.Settings.InitialCatalog;
connectionStringBuilder.Encrypt = this.Settings.Encrypt;
connectionStringBuilder.TrustServerCertificate = this.Settings.TrustServerCertificate;
SqlConnection connection = new SqlConnection(connectionStringBuilder.ConnectionString);
connection.AccessToken = this.Settings.TokenAuthenticator.GetAccessTokenAsync(DefaultScope).Result;
public async Task<string> GetAccessTokenAsync(IEnumerable<string> scopes)
{
X509Certificate2 certificate = this.GetCertificate();
ConfidentialClientApplicationOptions option = new ConfidentialClientApplicationOptions
{
AzureCloudInstance = this.CloudInstance,
ClientId = this.ApplicationId,
TenantId = this.TenantId,
};
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
.CreateWithApplicationOptions(option)
.WithCertificate(certificate)
.Build();
AuthenticationResult result = await app.AcquireTokenForClient(scopes)
.ExecuteAsync();
return result.AccessToken;
}
Expected behavior No exception. I should be able to authenticate a connection to my Azure SQL Database. I have run the same code on .Net Core console project, and it has been working.
Actual behavior I got this exception in my .Net Framework 4.7.2 console project: Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.PollBuilds —> System.AggregateException: One or more errors occurred. —> System.Security.Cryptography.CryptographicException: Key not valid for use in specified state.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.Utils._ExportKey(SafeKeyHandle hKey, Int32 blobType, Object cspObject)
at System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters)
at System.Security.Cryptography.RSA.ToXmlString(Boolean includePrivateParameters)
at Microsoft.Identity.Client.Platforms.net45.NetDesktopCryptographyManager.GetCryptoProviderForSha256(X509Certificate2 certificate)
at Microsoft.Identity.Client.Platforms.net45.NetDesktopCryptographyManager.SignWithCertificate(String message, X509Certificate2 certificate)
at Microsoft.Identity.Client.Internal.JsonWebToken.Sign(ClientAssertionCertificateWrapper credential, Boolean sendCertificate)
at Microsoft.Identity.Client.Internal.Requests.ClientCredentialHelper.CreateClientCredentialBodyParameters(ICoreLogger logger, ICryptographyManager cryptographyManager, ClientCredentialWrapper clientCredential, String clientId, AuthorityEndpoints endpoints, Boolean sendX5C)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.<SendTokenRequestAsync>d__22.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.<ExecuteAsync>d__2.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.<RunAsync>d__14.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.<ExecuteAsync>d__3.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Scm.Authentication.Settings.ClientCertificateSettings.<GetAccessTokenAsync>d__12.MoveNext()
— End of inner exception stack trace —
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task
1.get_Result()
at Scm.Authentication.AzureDatabaseBase.CreateConnection()
Possible Solution
Additional context/ Logs / Screenshots Add any other context about the problem here, such as logs and screebshots. Logging is described at https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/logging
Issue Analytics
- State:
- Created 4 years ago
- Comments:14 (4 by maintainers)
Top GitHub Comments
I agree @henning-krause We need to improve the exception to have a meaningfull and actionable message that the certificate should be exportable.
@henrik-me, @MarkZuber, @bgavrilMS We might want to provide a better error message when the certificate is not exportable? Or do we need to use the X509KeyStorageFlags.EphemeralKeySet flag ? to avoid the exception?