How to send authenticated MSMQ messages without using a domain account

For MSMQ, message authentication relies on a certificate being stored in Active Directory under the user account. These certificates are automatically created when the domain user logs in with their account on a machine (one certificate created per machine). Therefore if you are running a windows service that uses MSMQ, you need to run it under a domain user account that has previously logged in interactively. There is more background information on one of my posts from last year.

This poses a problem when you are running a service under the local machine account instead as an exception is raised:

0xC00E002F - MQ_ERROR_NO_INTERNAL_USER_CERT
"The internal Message Queuing certificate for the user does not exist."

Now it is possible to use a internal certificate for computer account. However, the certificate is not automatically created as you cannot log on as the computer account. To register a certificate for the computer account, you will need to call the MQRegisterCertificate function while under the Local System or Network Service account, as appropriate.

How you do this is up to you - adding some one-time certificate initialization code to your application, for example, or writing a small utility which just calls this API to register an internal certificate. An easy way to launch the latter under the System account is by using Task Scheduler to schedule a one-time task that runs it.

To verity if the certificate is registered successfully, you can open the registry and check if the following key is present:

HKLM\Software\Microsoft\MSMQ\CertStore

Or check in Active Directory (using ADSIEdit, for example) for the following attributes of the computer object :

  • mSMQDigests
  • mSMQSignCertificates

They would not have had any values before.

 

Reference

INFO: Storage of Private and Public Keys for MSMQ

 

[[Thanks to the very knowledgeable Xin Chen for the content.]]