-
-
Notifications
You must be signed in to change notification settings - Fork 110
MSIX APPX signing
Quick overview:
-
The format is zip based, with some restrictions (only STORED and DEFLATED compression methods are supported, multi volume archives are not allowed).
-
The extension is either
.appx
,.msix
,.appxbundle
or.msixbundle
. -
The signature is an entry named
AppxSignature.p7x
, it consists in a PKCS#7 signedData ASN.1 structure prefixed byPKCX
. -
The package contains a
[Content_Types].xml
file which must be modified with an extra entry for theAppxSignature.p7x
file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="dat" ContentType="appv/vfs-file" />
<Default Extension="png" ContentType="appv/vfs-file" />
<Default Extension="pri" ContentType="appv/vfs-file" />
<Default Extension="xml" ContentType="application/vnd.ms-appx.manifest+xml" />
<Override PartName="/AppxBlockMap.xml" ContentType="application/vnd.ms-appx.blockmap+xml" />
<Override PartName="/AppxSignature.p7x" ContentType="application/vnd.ms-appx.signature" />
</Types>
-
signtool requires the hash algorithm to match the algorithm defined in the
AppxBlockMap.xml
entry (as an URI in theHashMethod
attribute of the rootBlockMap
element, see MSIX package signing). The values allowed are:- SHA-256: http://www.w3.org/2001/04/xmlenc#sha256
- SHA-384: http://www.w3.org/2001/04/xmldsig-more#sha384
- SHA-512: http://www.w3.org/2001/04/xmlenc#sha512
But when the signature is verified this requirement isn't checked (at least on Windows 10).
-
The spcSipInfoObjID version is
0x01010000
and the UUID is:-
4BDFC50A-07CE-E24D-B76E-23C839A09FD1
for a package (.appx
or.msix
) -
B3585F0F-DEAA-9A4B-A434-95742D92ECEB
for a bundle (.appxbundle
or.msixbundle
)
-
-
Packages and bundles can be differentiated by their content:
- package have an
AppxManifest.xml
file - bundles have an
AppxBundleManifest.xml
file
- package have an
-
The digest in the spcIndirectDataContext structure is a concatenation of several digests. It starts with a header
APPX
and is followed by 4 or 5 names of 4 bytes in a specific order, followed by a hash (see the DigestName enum). The length of the hash depends on the algorithm used (32 bytes for SHA-256, 48 bytes for SHA-384 and 64 bytes for SHA-512). With SHA-256 the spcIndirectDataContext structure looks like this:
00000000 41 50 50 58 41 58 50 43 FC AB FD 6D E4 B9 CA 86 APPXAXPCü«ýmä¹Ê.
00000010 3B 92 61 66 B1 91 A2 01 F9 5C 39 97 0B 51 6F D6 ;.af±.¢.ù\9..QoÖ
00000020 03 37 7A AF F5 10 9D 36 41 58 43 44 23 3E 5C 59 .7z¯õ..6AXCD#>\Y
00000030 3B 6B E0 F4 D6 11 5A FA 5F 9F 4C 38 D6 57 7C 76 ;kàôÖ.Zú_.L8ÖW|v
00000040 78 5B EB F2 1D 07 43 B3 E6 AF 08 F7 41 58 43 54 x[ëò..C³æ¯.÷AXCT
00000050 C9 86 D8 E1 3E F8 0D 82 BD 75 42 7B 9C 44 42 23 É.Øá>ø..½uB{.DB#
00000060 74 6D 1B B6 EC A8 55 6F 35 08 B8 AE 39 4B C1 19 tm.¶ì¨Uo5.¸®9KÁ.
00000070 41 58 42 4D 2B E5 5D EF 3E 00 08 EE 70 1E AB 04 AXBM+å]ï>..îp.«.
00000080 C2 14 17 10 C6 DE 65 EE E8 26 CD 74 EC 16 13 32 Â...ÆÞeîè&Ítì..2
00000090 75 F2 CF 3A uòÏ:
-
These partial digests are computed as follows (and in this order):
-
AXPC
: digest of the file records, i.e. from offset 0 to the last byte before the first central directory file header. The records must be hashed in the order of the central directory (which may not be sorted by offset). When verifying a signed file, theAppxSignature.p7x
entry must be skipped. -
AXCT
: digest of the uncompressed content of[ContentTypes].xml
-
AXBM
: digest of the uncompressed content ofAppxBlockMap.xml
-
AXCD
: digest of the central directory. The central directory is hashed completely from the first entry to the end of the file after[Content_Types].xml
is modified and before the signature is added to the file, even if it's altered after adding the signature (which means that the signature verification process involves rewriting the central directory as if it didn't contain the signature, this involves changing the number of entries, size and offsets in the end of central directory records). -
AXCI
: digest of the uncompressed content ofAppxMetadata/CodeIntegrity.cat
, only if the package contains this file.
-
-
The app manifest publisher name (CN=Contoso) must match the subject name of the signing certificate (CN=Contoso, C=US) (see * https://learn.microsoft.com/en-us/windows/msix/package/signing-known-issues). This means only the publisher of the package can sign it, unlike other file formats.
-
When signing a bundle, signtool also signs the embedded packages. However when the bundle signature is verified, the package signatures aren't checked. So a signed bundle could contain unsigned packages and still be valid.
-
A bundle and its embedded packages must all use the same hash algorithm in their respective
AppxBlockMap.xml
file.
- Windows Terminal (msix bundle)
- MSIX Hero (msix)
- https://github.com/facebookarchive/fb-util-for-appx
- https://github.com/sassoftware/relic/tree/master/signers/appx
- https://github.com/microsoft/msix-packaging/blob/johnmcpms/signing/src/inc/internal/AppxSignature.hpp https://github.com/microsoft/msix-packaging/blob/johnmcpms/signing/src/msix/unpack/AppxSignature.cpp