]> MSMQ: The signature is invalid. 🌐:aligrant.com

MSMQ: The signature is invalid.

Alastair Grant | Friday 27 September 2019

I have recently deployed an application to a new server which is failing to send authenticated MSMQ messages locally.

The Windows Application log was recording Event ID 2196:

Message Queuing failed to verify digital signature of a message sent to queue PRIVATE=xxxx\xxx. The message was rejected. A negative arrival acknowledgement will be sent if requested by the sender. This event is logged at most once per 600 seconds.

Not massively helpful.  But my messages were being delivered to "System Queues\Transactional dead-letter messages", accompanied with the class "The signature is invalid.".  The Sender tab correctly lists the user sending it, but the message isn't marked as authenticated, and the Hash algorithm is unknown.

The Microsoft documentation on this event suggests one of the following causes:

  • Weak hash function issues
  • Bad user certificate
  • Corruption of the message in transit

Weak hash functions are a result of using an old application, or communicating across-servers using MSMQ, with the downstream server running an older version of MSMQ.  In reality, nobody should be running old MSMQ servers any more as they've all dropped out of support.

My app is built on .NET 4 which does support the latest algorithms for MSMQ, and this was a local queue.  Not a weak hash function.

Corruption of the message in transit doesn't apply either, as the message is only being stored locally and worked fine if authentication was disabled completely.

Bad user certificate being the one left, and marries up with the error in the dead-letter queue.  But when using internal-certificates with MSMQ, there isn't really anything you can do about the certificate in use, apart from refresh it.

MSMQ certificates

In order to use directory-integrated authenticated message queue, a certificate needs to be generated and registered on the server running the source queue.  This has to be done under the credentials that the application will be communicating in.

To create a certificate you need to:

  1. Load Computer Management under the credentials of the application using the Run As... feature (shift right click) after locating the short-cut (search start, right click, open file location).
  2. Right click Message Queuing and go to Properties
  3. Select the User Certificate tab
  4. Click Renew...
  5. Click Register...

Renew will generate a new private/public key pair for that user to use locally with MSMQ.  It will automatically register, but you can do this manually if you want too.  Register takes the public part and writes it into the mSMQSignCertificates attribute in the user's Active Directory object.

You can view which certificates are available to the current user in AD by clicking the View... button.

NB: If you're using IIS, make sure you set the App Pool to load the user profile, otherwise the certificate won't be available to the application.

User certificates cannot be obtained.

But for me, when I clicked the View, or Remove buttons I was being presented with the error:

User certificates cannot be obtained.

Error: There is an internal Active Directory Domain Services error.

Although I could seem to register a certificate successfully, I suspect that this indicated MSMQ might have a problem with retrieving the certificates at runtime and thus cause an invalid signature error.

After much troubleshooting it became apparent that this wasn't a problem on freshly created user accounts.

To resolve the error the following can be done:

  1. Use Active Directory Users and and Computers to locate the effected account (navigate, don't search).
  2. Open properties and select Attribute Editor tab
  3. Find the entries: mSMQDigests and mSMQSignCertificates
  4. Edit them and remove/clear the data
  5. Commit your change
  6. Open the Messaging Queuing console with the effected account on the device that will be creating messages, and navigate to the User Certificate page as above.
  7. Click View - problem should have now gone away and a blank list of certificates shown.  If the error persists you may need to wait for replication.
  8. Click Register to re-register the existing account/computer combined certificate into the Active Directory object.

What causes the entry in Active Directory to become corrupt/unreadable I do not know, and I don't fancy paying for a Microsoft support to find out, now that I have a workaround.

If you have lots of servers, you may need to take a different approach, such as creating a service account-per-server if it continues to be problematic.

Breaking from the voyeuristic norms of the Internet, any comments can be made in private by contacting me.