“The profile for the user is a temporary profile” Error Even After Granting Private Key Read Rights

,

Recently, while helping a client deploy a wsHttpBinding Windows Communication Foundation web service configured with message security, we encountered the following error: “The profile for the user is a temporary profile.” As is sometimes the case with WCF certificate security issues, the initial error message’s description did not come close to describing the actual problem.

In the exception chain below, the second exception clued me that the problem might have to do with the web service lacking the right to read the service certificate’s private key. We tried giving the web service’s account read rights to the private key by using the Certificate MMC snap-in and via findprivatekey.exe/cals.exe. In both cases, no go—the problem remained.

[CryptographicException: The profile for the user is a temporary profile.
]
   System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer) +450
   System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle) +158
   System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair() +231
   System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey() +537
   System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate) +78

[ArgumentException: It is likely that certificate 'E=someone@example, CN=Some Name, OU=Some OU, O=Some Company, L=Some Location, S=Some State, C=US' may not have a private key that is capable of key exchange or the process may not have access rights for the private key. Please see inner exception for detail.]
   System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate) +16621133
   System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement) +94
   System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement requirement) +50
   System.ServiceModel.Security.SymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout) +180
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +789
   System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) +81
   System.ServiceModel.Channels.SecurityChannelListener`1.OnOpen(TimeSpan timeout) +398
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +789
   System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +283
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +789
   System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +126
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +789
   System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +255
   System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +1172

[ServiceActivationException: The service '/service.svc' cannot be activated due to an exception during compilation.  The exception message is: It is likely that certificate 'E=someone@example, CN=Some Name, OU=Some OU, O=Some Company, L=Some Location, S=Some State, C=US' may not have a private key that is capable of key exchange or the process may not have access rights for the private key. Please see inner exception for detail..]
   System.Runtime.AsyncResult.End(IAsyncResult result) +901424
   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +178638
   System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +107

Then it occurred to me that there might be a problem with how the certificate was installed on the server. The certificate had been installed by double-clicking on the certificate file. By default, this process places the certificate in the current user’s certificate store. As the certificate was for a service, it needed to be moved into the machine store so it had been dragged into the correct store (in MMC).

FindPrivateKey.exe revealed that the private key file was still located under the installing user’s user profile directory. Dragging the certificate between stores in MMC didn’t move the private key to the machine store’s directory.

Ah! The solution was simple: install the certificate directly into the machine store. In MMC, we deleted the certificate then imported it directly into the machine store. After giving the WCF service’s account read rights to the private key, the error was resolved!

 

 


Leave a Reply

Your email address will not be published. Required fields are marked *