Search code examples
c#emailencryptionoutlookmsg

How to check if .msg file (saved outlook email) encrypted?


I have a number of .msg files, which are saved emails from Outlook 2016. Some emails are encrypted, some have attachments. How to figure out if email encrypted? It should work on the server which do not have Office installed. Now I'm writing prove of concept console app, but this code also could be used in web app. Could be subsequent tasks to a get list of recipients if it's encrypted. Is it even possible? It may require decryption, which could be .. difficult, if you are not a recipient. Observation: if I search email string "[email protected]" in the .msg file, then I can find it only if email unencrypted.

Example of creating email in the Outlook:

Error opening encrypted email in the Outlook if you are not a recipient:

Normal and encrypted .msg files in Notepad

My pseudo code below. I installed libary Microsoft.Office.Interop.Outlook by NuGet:

using Microsoft.Office.Interop.Outlook;

namespace EmlReader
{
    class Program
    {
        static void Main(string[] args)
        {
            const string emailPath = @"C:\Test\temp-saved-mail-enc.msg";
            Microsoft.Office.Interop.Outlook.MailItem mailItem = ... load from file  // how?
            Outlook.Application POfficeApp = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");  // note that it returns an exception if Outlook is not running
            Outlook.MailItem POfficeItem = (Outlook.MailItem)POfficeApp.ActiveInspector().CurrentItem; // now pOfficeItem is the COM object that represents your .eml file
        }
    }
}

PS Related article written by me in relation to Outlook Plugin: How to check if outlook email encrypted? But it related to workstation, not to the server.


Solution

  • It's been for a while, so I'm answering it the way I did it in the past, which is not perfect, but works. I believe it's self explanatory, for more details there is similar discussion here. Code also check for "signed" emails.

        // let's detect only encrypted emails
        // ignore signed emails
        private static dynamic IsEmailEcrypted(Outlook.MailItem mailItem)
        {
            //Value               Const          Description
            //NONE                0x0000         Message has no security
            //SIGNED              0x0002         Message is signed
            //ENCRYPTED           0x0001         Message is encrypted
            //SIGNED & ENCRYPTED  0x0003         Message is signed and encrypted  
            //SIGNED & ENCRYPTED  00100011 = 35  Message is signed and encrypted  // x35 ??
    
            const string OutlookPropertyAccessorSchema = "http://schemas.microsoft.com/mapi/proptag/0x6E010003";
            Outlook.PropertyAccessor outlookPropertyAccessor = mailItem.PropertyAccessor;
            int header = outlookPropertyAccessor.GetProperty(OutlookPropertyAccessorSchema);
    
            if (header == 1 || header == 3 || header == 35)
                return true;
    
            return false;
        }