Open format specification
An open, documented XML format for carrying the AES content keys of an encrypted Digital Cinema Package — so that a package encrypted today can still have a KDM issued for it years from now, from any workstation.
When a DCP is encrypted, the AES content keys exist for exactly one moment: while the package is being written. They are not stored in the package, and they cannot be recovered from it. Lose them and the DCP is permanently unopenable — no KDM can ever be issued for it, by anyone.
So the keys have to be written down somewhere. That somewhere should not be a private format belonging to one application, because the whole point is that it outlives the session that produced it and can be read by whatever tool is at hand in five years. This is that format.
A digest describes one package: which compositions it contains, which reels each composition has, and for every encrypted asset, the KeyId the CPL references and the AES key that opens it.
The structure here is deliberately the same as the digest format written by easyDCP and other Fraunhofer-derived tools, which uses the namespace http://www.fhg.de/2009/04/02/dcpdig. That format is widely used and has, as far as we can find, never been published: the namespace URI resolves to nothing and there is no specification to check an implementation against.
We did not want a key failsafe — the one file standing between a finished master and an unopenable one — resting on an undocumented identifier belonging to someone else. So this document exists, and AlphaDCP writes this namespace.
The practical consequences are worth stating plainly:
A digest is plaintext AES keys. Anyone holding this file can decrypt the package it describes, completely and without a KDM. It is exactly as sensitive as the unencrypted master.
It must never be placed inside the DCP folder, never shipped to an exhibitor, and never committed to a repository or attached to a ticket. Store it as you would store the film itself. Encrypt it at rest if your workflow allows.
A digest is the mastering facility's copy. The thing you send to a cinema is a KDM: keys wrapped for one specific server's certificate, valid for a stated window. The two must never be confused, and the digest is the one that has no expiry and no recipient.
Every value below is fabricated. A digest contains live AES content keys, so no real one may be used as documentation — not in a specification, not in a bug report, not in a support ticket.
<?xml version="1.0" encoding="UTF-8"?>
<DCPKeyDigest xmlns="https://alpha-sub.com/ns/dcp-digest/1">
<Version>1</Version>
<Conformity>SMPTE</Conformity>
<InteropMode>false</InteropMode>
<CompositionList>
<Composition>
<Id>urn:uuid:11111111-1111-1111-1111-111111111111</Id>
<AnnotationText>ExampleFilm_FTR-1_F-185_EN-XX_51_2K_20260101_SMPTE_OV</AnnotationText>
<ContentTitleText>ExampleFilm_FTR-1_F-185_EN-XX_51_2K_20260101_SMPTE_OV</ContentTitleText>
<ReelList>
<Reel>
<Id>urn:uuid:22222222-2222-2222-2222-222222222222</Id>
<MainPicture>
<Id>urn:uuid:33333333-3333-3333-3333-333333333333</Id>
<AnnotationText>reel 1 picture</AnnotationText>
<KeyId>urn:uuid:44444444-4444-4444-4444-444444444444</KeyId>
<Key>00000000000000000000000000000000</Key>
</MainPicture>
<MainSound>
<Id>urn:uuid:55555555-5555-5555-5555-555555555555</Id>
<KeyId>urn:uuid:66666666-6666-6666-6666-666666666666</KeyId>
<Key>11111111111111111111111111111111</Key>
</MainSound>
<MainSubtitle>
<Id>urn:uuid:77777777-7777-7777-7777-777777777777</Id>
<KeyId>urn:uuid:88888888-8888-8888-8888-888888888888</KeyId>
<Key>22222222222222222222222222222222</Key>
</MainSubtitle>
</Reel>
</ReelList>
</Composition>
</CompositionList>
</DCPKeyDigest>
The document element. Carries the namespace declaration.
| Element | Cardinality | Meaning |
|---|---|---|
| Version | 1 | Format version. 1 for this specification. A reader that does not recognise the value should refuse the document rather than guess. |
| Conformity | 1 | SMPTE or INTEROP. Which packaging standard the described DCP follows. |
| InteropMode | 1 | true or false. Redundant with Conformity and retained for compatibility with existing readers. The two must agree; on disagreement, Conformity wins. |
| CompositionList | 1 | Container for one or more Composition. |
One CPL. A package with several compositions — a feature plus its trailers, or one CPL per subtitle language sharing the same picture and sound — has one Composition each. The same asset key legitimately appears under more than one composition, because each CPL's KDM must carry the keys for every asset that CPL references.
| Element | Cardinality | Meaning |
|---|---|---|
| Id | 1 | The CPL's UUID, as urn:uuid:…. |
| AnnotationText | 0–1 | Human-readable label. Conventionally the CPL name. |
| ContentTitleText | 0–1 | The CPL's ContentTitleText. |
| ReelList | 1 | Container for one or more Reel, in playback order. |
One reel of the composition. A reel holds at most one asset of each kind — this is a property of the underlying CPL, and a reader is entitled to take the first of each and ignore any duplicate.
| Element | Cardinality | Meaning |
|---|---|---|
| Id | 1 | The reel's UUID, as urn:uuid:…. |
| MainPicture | 0–1 | The reel's encrypted picture asset. |
| MainSound | 0–1 | The reel's encrypted sound asset. |
| MainSubtitle | 0–1 | The reel's encrypted subtitle asset. |
Unencrypted assets are omitted. A reel whose picture is encrypted but whose sound is not contains only MainPicture. Assets should be written in the order above.
MainPicture, MainSound and MainSubtitle share one content model. The element name is what identifies the key's type — SMPTE 430-1 calls these MDIK, MDAK and MDSK respectively — so it carries meaning and must not be generalised.
| Element | Cardinality | Meaning |
|---|---|---|
| Id | 1 | The track file's asset UUID, as urn:uuid:…. Matches the asset's Id in the CPL and the PKL. |
| AnnotationText | 0–1 | Human-readable label for the asset. |
| KeyId | 1 | The KeyId the CPL states for this asset, as urn:uuid:…. This is the join: a KDM is built by matching CPL KeyIds against digest entries. |
| Key | 1 | The AES-128 content key: exactly 32 lowercase hexadecimal characters, no prefix, no separators. |
https://alpha-sub.com/ns/dcp-digest/1 on the document element.Key as 32 lowercase hex characters.urn:uuid: form, lowercase.Reel. A source that somehow holds two must be split across additional reels rather than have keys silently dropped.KeyId and Id values with or without the urn:uuid: prefix, case-insensitively.Key in either case, with or without a 0x prefix.The conventional extension is .dcpdig, written beside the package directory and named for it:
MASTERS/
├── ExampleFilm_FTR-1_F-185_EN-XX_51_2K_20260101_SMPTE_OV/
│ ├── ASSETMAP.xml
│ └── …
└── ExampleFilm_FTR-1_F-185_EN-XX_51_2K_20260101_SMPTE_OV.dcpdig
Beside the package, not inside it. A digest inside the DCP folder ships with the DCP, which hands the keys to everyone the package is sent to and defeats the encryption entirely.
AlphaDCP writes this format when it encrypts a package, and reads this format, the Fraunhofer digest, and its own earlier JSON key files. Its reader and writer are covered by a round-trip test suite that includes a verbatim Fraunhofer sample.
This specification is published so that any tool may read or write the format freely. No permission is required and no licence applies to the format itself.