Error encrypting mail with MailMessage.Encrypt

0 votes
asked Jun 22, 2020 by obartelt (840 points)

I get the following error when encrypting a mail with MailMessage.Encrypt, but couldn't find anything in the source or online regarding this error message:

"No recipient has a certificate with correct key usage for encryption."

The certificate is valid and has the following purposes listed (the first would read "Protects E-Mail messages" in English):

"Schützt E-Mail-Nachrichten"

Any idea what's causing this and how I can circumvent it?

Applies to: Rebex Secure Mail

1 Answer

0 votes
answered Jun 23, 2020 by Lukas Matyska (59,010 points)
edited Jun 23, 2020 by Lukas Matyska

According to RFC 5652 - section 6.2.1:

a recipient X.509 version 3 certificate that contains a key usage
extension MUST assert the keyEncipherment bit

Please, check the Key Usage of your certificate. It should contain:

Key Encipherment (20)

Also, the mentioned OID does not refer to Email protection, it refers to "Global security levels". The correct OID for Email protection is (defined by RFC 5280 - section

commented Jun 24, 2020 by obartelt (840 points)
Ok, thanks for the clarification. Is there any onboard mechanism that I can use to check if the certificate is valid for e-mail encryption? Right now I'm only checking if it is valid, but that seems to not be enough in this case :-(
commented Jun 24, 2020 by Lukas Matyska (59,010 points)
There is no built-in method to check this, because certificates are not used for S/MIME only. However you can do simple check:

bool hasEncryptionUsage = (cert.GetIntendedUsage() & KeyUses.KeyEncipherment) != 0;

string[] enhancedUsageOids = cert.GetEnhancedUsage();
bool hasMailProtection = enhancedUsageOids == null ||
                            enhancedUsageOids.Contains(ExtendedUsageOids.EmailProtection) ||

The certificate can be used to encrypt an email if both `hasEncryptionUsage` and `hasMailProtection` are TRUE.

To complete the list, for signing an email, you should check:

bool hasSigningUsage = (cert.GetIntendedUsage() & KeyUses.DigitalSignature) != 0;
commented Jun 24, 2020 by obartelt (840 points)
Thanks, that was exactly what I needed! :-)