EML, EMLX and MSG: what is inside a saved email

A client hands you «the email» on a USB stick. It may be an .eml file, an .emlx copied out of the Apple Mail library, or an .msg saved from Outlook. They look like three ways of saying the same thing, and they are not: two keep the message exactly as it arrived, the third breaks it into fields and does not keep its original form. In a forensic examination, that difference decides whether a hash or a signature can still be checked.

What an email physically is

A mail message is text. RFC 5322 defines it: a block of headers (From, To, Date, Message-ID, and the Received lines each server adds at the top along the way), a blank line, and the body. MIME adds structure: the body can be split into parts — plain text, the HTML version, images referenced by the HTML, attachments encoded in base64 — each with its own Content-Type headers.

The consequence, for anyone examining a message: whatever can be verified is computed over exact bytes. An S/MIME signature — and therefore the provider's signature on an Italian PEC certified email — covers one MIME part exactly as written, line endings included. Rewrite it so that it looks the same but differs in its bytes, and it can no longer be verified, even though nobody tampered with anything.

Three containers for the same message

EML — the file is the message the file, from first byte to last From: Anna Rossi <anna@example.com> To: Mark White <mark@example.org> Subject: Minutes Date: Tue, 15 Sep 2026 10:00:00 +0200 Message-ID: <v1@example.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 — blank line — Minutes attached. 240 bytes SHA-256 adf82828…850ad0ca file hash = message hash EMLX — the message in an envelope the Apple Mail .emlx file 240 length line, in bytes the 240 bytes of the message identical to the EML, byte for byte SHA-256 adf82828…850ad0ca <key>date-received</key> <integer>1789459207</integer> <key>flags</key><integer>5</integer> 2026-09-15 08:00:07Z · read, replied plist: mailbox data, not message data MSG — the message in pieces Compound File: one stream per field __substg1.0_001A001F class __substg1.0_0037001F subject __substg1.0_007D001F headers __substg1.0_1000001F plain text __substg1.0_10090102 compressed RTF __recip_version1.0_#00000000 __attach_version1.0_#00000000 __substg1.0_3707001F smime.p7m __substg1.0_370E001F multipart/signed __substg1.0_37010102 the envelope, intact only when the class is IPM.Note.SMIME.MultipartSigned no RFC 5322 text inside: it must be rebuilt EML and EMLX keep the bytes that arrived, with the same hash. MSG keeps the fields: the message has to be put back together. Sample content: the 240-byte message in the first column, lines ending in CRLF.
The same email in three files. The dashed box in the MSG shows the part that exists only when Outlook kept the envelope of a signed message.

EML: the file is the message

An .eml is the RFC 5322 message written to disk, first byte to last. There is no wrapper: the hash of the file is the hash of the message, and any tool can read it without interpreting anything.

EMLX: the message inside Apple Mail's envelope

Apple Mail stores each message in an .emlx made of three parts: a first line holding the byte count of the message, the message itself, and at the end an XML plist with mailbox metadata. The embedded message is identical, byte for byte, to the one received: extracting it changes nothing, and in the figure its hash matches the EML.

The plist is extra information of a different kind: it says nothing about the message, only what the mailbox did with it. date-received is when Apple Mail received it, in seconds since the Unix epoch; flags is an integer whose bits say whether the message was read, replied to, forwarded, flagged. Those bits have no public specification: Probatio names the ones that have been stable and observed in real files, and always reports the whole integer, which is the actual data.

Two variants to recognise. In a .partial.emlx Apple Mail has detached the attachment contents and stored them elsewhere: the attachments appear but are empty, and Probatio says so. If the first line declares more bytes than the file holds, the message is truncated and is read as far as it goes, with a warning.

MSG: the message taken apart into properties

An Outlook .msg is a Compound File, the same container as the old .doc. There is no message text inside: there is a set of MAPI properties, one per stream — 0x0037 the subject, 0x1000 the plain text, 0x1013 the HTML, 0x007D the transport headers — while recipients and attachments are sub-storages. Outlook took the message that came from the server, dismantled it into its fields, and kept the fields.

To read it, then, the message has to be rebuilt. Probatio tells three cases apart and states which one applies:

  1. Transport headers present (0x007D): the headers are the original ones, but body and attachments are reassembled from properties. The MIME structure is new.
  2. No transport headers: the message never went through a server — a draft, an item created in Outlook, or a save from a program that does not keep them. Sender, recipients and date come from properties, and there is no server path to examine.
  3. S/MIME envelope preserved: the good case, which deserves its own section.

This is why, when it opens an MSG, Probatio shows two hashes: one of the file, which is the evidence, and one of the rebuilt message, which should not be cited as the hash of anything that exists outside the program.

The case that saves the signature: IPM.Note.SMIME.MultipartSigned

When Outlook saves an S/MIME signed message, it can keep the signed envelope as it is: the message class (property 0x001A) becomes IPM.Note.SMIME.MultipartSigned and the envelope goes into an attachment named smime.p7m of type multipart/signed. Transport headers plus that attachment give back the original message byte for byte: the signature can still be verified, and for a PEC so can the provider's signature. That is why a PEC saved as MSG can still go through PEC verification.

One detail that needed a fix, and is worth knowing: the envelope does not always start with Content-Type. On a 2019 PEC receipt saved by Outlook it starts with MIME-Version: 1.0 and only then Content-Type. A check that only looks at the first bytes mistakes it for a binary blob, wraps it again, and the signature can no longer be found. Probatio recognises the envelope from the whole header block — well-formed lines up to the blank line, with a Content-Type among them — and, if the envelope already carries its own MIME-Version, it does not add a second one: the bytes stay the original ones.

If the envelope is there but the transport headers are missing, the signed body is original and the outer headers are rebuilt; if the class says S/MIME but no envelope can be found, Probatio says so.

winmail.dat and compressed RTF

When Outlook sends a message in «RTF format» to an outside recipient, it packs attachments and formatting into a single attachment, winmail.dat (TNEF format). Every program other than Outlook shows only that opaque file: the real attachments are there, but out of sight. It is the most treacherous kind of «missing attachment», because the recipient can say in good faith that no document ever arrived. Probatio opens the winmail.dat and lists its attachments as children of that node, each with its own hashes.

Outlook's other legacy lives inside the MSG: many messages do not have the HTML body as a property of its own, but keep it wrapped in compressed RTF (property 0x1009, the «LZFu» algorithm described in MS-OXRTFCP). The original HTML sits in the RTF's htmltag groups, surrounded by rendering text that has to be discarded. Probatio decompresses the RTF and recovers the HTML: without that step, the body of those messages would come out empty.

Attachments are a tree, not a list

An attached message has attachments of its own, a winmail.dat holds files, a PEC carries the original message inside postacert.eml. Probatio builds the whole tree and gives each node a path identifier — 1/0 is the first child of the second attachment — so that it can be saved or opened without ambiguity. Nested messages are opened even when they are attached as .eml, .msg or .emlx files rather than as message/rfc822.

Attachments of «Minutes.eml»: the tree Probatio builds id name declared type type from bytes bytes SHA-256 0 invoice.pdf application/pdf PDF, consistent 15 1e7313ac…4e0bbfd3 1 winmail.dat application/ms-tnef TNEF · 1 attachment 1/0 photo.jpg image/jpeg PNG: not a JPEG 8 4c4b6a3b…2d20dab6 2 forward.eml message/rfc822 nested message 2/0 note.txt text/plain text 15 084d1fd9…17a3a2a9 winmail.dat: other mail programs show only this file. The real document is node 1/0. The name says JPEG, the first 8 bytes say PNG: a mismatch is flagged only when recognition is certain. Path identifiers (1/0, 2/0) let you save or open that node, and no other.
Sample contents: invoice.pdf is «%PDF-1.7», newline, «%%EOF», newline (15 bytes); photo.jpg is the 8-byte PNG signature, 89 50 4E 47 0D 0A 1A 0A; note.txt is «See you at 10.» and a newline (15 bytes). SHA-256 computed with shasum -a 256, shortened; the containers' hashes are left out.

For each node Probatio shows MD5, SHA-1 and SHA-256, the type declared in the message and the type recognised from the bytes. When the name says one thing and the content another, it flags it — but only when recognition is certain: generic text or an unrecognised binary contradicts no extension, and a .docx that turns out to be a ZIP is not an anomaly, because a .docx is a ZIP. Magic bytes have a guide of their own: entropy and disguised files.

The hash of a text attachment is computed over its original bytes, removing only the transfer encoding (base64 or quoted-printable), not over text already converted to UTF-8: otherwise an ISO-8859-1 .txt would get a hash different from that of the attached file.

Converting without losing the signature

Probatio saves the open message — nested ones too — as EML, EMLX, MSG or headers only. Three rules apply: the same format is an identical copy; the RFC 5322 bytes are kept wherever the format allows it; whatever is rebuilt is declared.

From → toWhat happensIs the message unchanged?
Same formatCopy of the file, byte for byteYes
EML → EMLXMessage embedded unchanged; the plist carries a received date taken from the message and the «read» flagYes
EMLX → EMLEmbedded message extracted; Apple Mail metadata has no place in an EML and is not carried overYes
EML → MSG, signedOutlook's IPM.Note.SMIME.MultipartSigned form, with the envelope kept byte for byteThe signature stays verifiable
EML → MSG, unsignedOriginal headers in 0x007D, body and attachments broken into properties, as Outlook doesNo: the MSG does not contain the message
MSG → EML or EMLXMessage rebuilt, marked with an X-Probatio-Conversione headerNo, and it says so

The X-Probatio-Conversione header states that the message was rebuilt from an MSG, when, and that body and attachments come from MAPI properties: whoever receives that EML a year later knows it without having to ask. With a preserved signed envelope the header joins the outer ones and does not touch the signed part: a PEC that makes the round trip EML → MSG → EML stays valid, and an EML that passes through EMLX comes back identical to the starting file.

Looking without being seen

The HTML body of an email is part of the evidence, and it can be hostile. Probatio's preview parses it into an inert document and strips scripts, iframes, embedded objects, <base>, <meta> and every on… attribute; it disables forms and makes links impossible to follow. The real address of each link stays visible on hover, because in an examination what matters is where a link leads, not going there.

Remote images are not loaded, and the reason has a name: the tracking pixel. It is a tiny, often invisible image with a different address for every recipient: when the mail program fetches it, the sender's server records that the message was opened, when, and from which IP address. In phishing it confirms that the address is live; in a forensic examination it would tell whoever sent the message that it is being examined, and from where.

If they are really needed, they are loaded only after explicit confirmation, and the app fetches them: no cookies or Referer, only from public addresses (a message must not be able to probe the office network), accepting only real images and recording the servers contacted in the activity log. Background images in CSS stay blocked.

Where the bytes are read

Everything that reads the bytes of the message — EML, EMLX, MSG, winmail.dat, RTF, MIME — runs in a separate process. On macOS it is confined by the system sandbox: no network, writes only to its own working folder, no launching of other programs, memory and CPU limits. If that component is missing, the message is not opened. Every operation carries the hash shown on screen: if the file on disk has changed in the meantime, it refuses to act on content different from what you saw.

Limits

  • An MSG without an S/MIME envelope is a rebuilt message. Hashes and signatures computed on it do not match those of the original. The evidence is the .msg file; the reconstruction is there to read it.
  • In MSG files, attachments by reference (Outlook keeps only the file path) do not contain the file, and embedded OLE objects are not rebuilt. Probatio reports both cases.
  • From a winmail.dat the attachments are extracted. Any RTF body inside it is not shown, and an item that TNEF keeps only as an embedded object (an attached message, for instance) is not extracted.
  • A .partial.emlx has empty attachments: their content lives in an Apple Mail folder, outside the file.
  • Probatio opens one message per file. Whole-mailbox archives, mbox and PST, are not supported; a file over 256 MB is refused with a note that it is probably one of those.
  • On Windows isolation is weaker: a separate process with a time limit, without the network and filesystem confinement that macOS has, and without memory limits.

In practice: which format to ask for and keep

  1. Ask for EML when there is a choice: it is the message as it arrived, with nothing interpreted, and the hash of the file is the hash of the message.
  2. An EMLX is as good as an EML, plus mailbox metadata. Keep it as it is: received date and flags are extra data, not clutter. Check that it is not a .partial.emlx.
  3. If you receive an MSG, look at the class. IPM.Note.SMIME.MultipartSigned means the signed envelope is there and the signature can be verified. Otherwise, state in your report that the message is rebuilt, and cite the hash of the .msg file. If the source is still available, ask for the same message as EML too.
  4. Hash the file you received before anything else, and keep that file. Conversions are for reading or delivering, not for replacing the evidence.
  5. Always open winmail.dat files. The document that «never arrived» is often in there.
  6. Do not load remote images unless the examination requires it. If it does, note that you did, and when.

Probatio's Email viewer recognises the three formats from their bytes, not their extension: an .msg renamed to .eml is still an MSG. A saved email is worth what it preserves of the message that arrived, and knowing which of the three files you are holding is the first thing to write in the report.