1 <h1>CRX Package Format
</h1>
5 CRX files are ZIP files with a special header and the
<code>.crx
</code> file
9 <h2 id=
"package_header">Package header
</h2>
12 The header contains the author's public key and the extension's signature.
13 The signature is generated from the ZIP file using SHA-
1 with the
14 author's private key. The header requires a little-endian byte ordering with
15 4-byte alignment. The following table describes the fields of
16 the
<code>.crx
</code> header in order:
19 <table class=
"simple">
21 <th>Field
</th><th>Type
</th><th>Length
</th><th>Value
</th><th>Description
</th>
24 <td><em>magic number
</em></td><td>char[]
</td><td>32 bits
</td><td>Cr24
</td>
26 Chrome requires this constant at the beginning of every
<code>.crx
</code>
31 <td><em>version
</em></td><td>unsigned
int
</td><td>32 bits
</td><td>2</td>
32 <td>The version of the
<code>*.crx
</code> file format used (currently
2).
</td>
35 <td><em>public key length
</em></td><td>unsigned
int
</td><td>32 bits
</td>
36 <td><i>pubkey.length
</i></td>
38 The length of the RSA public key in
<em>bytes
</em>.
42 <td><em>signature length
</em></td><td>unsigned
int
</td><td>32 bits
</td>
43 <td><i>sig.length
</i></td>
45 The length of the signature in
<em>bytes
</em>.
49 <td><em>public key
</em></td><td>byte[]
</td><td><i>pubkey.length
</i></i></td>
50 <td><i>pubkey.contents
</i></td>
52 The contents of the author's RSA public key, formatted as an X509
53 SubjectPublicKeyInfo block.
57 <td><em>signature
</em></td><td>byte[]
</td><td><i>sig.length
</i></td>
58 <td><i>sig.contents
</i></td>
60 The signature of the ZIP content using the author's private key. The
61 signature is created using the RSA algorithm with the SHA-
1 hash function.
66 <h2 id=
"extensions_contents">Extension contents
</h2>
69 The extension's ZIP file is appended to the
<code>*.crx
</code> package after the
70 header. This should be the same ZIP file that the signature in the header
74 <h2 id=
"example">Example
</h2>
77 The following is an example hex dump from the beginning of a
<code>.crx
</code>
82 43 72 32 34 #
"Cr24" -- the magic number
83 02 00 00 00 #
2 -- the crx format version number
84 A2
00 00 00 #
162 -- length of public key in bytes
85 80 00 00 00 #
128 -- length of signature in bytes
86 ........... # the contents of the public key
87 ........... # the contents of the signature
88 ........... # the contents of the zip file
92 <h2 id=
"scripts">Packaging scripts
</h2>
94 Members of the community have written the following scripts to package
95 <code>.crx
</code> files.
98 <h3 id=
"ruby">Ruby
</h3>
100 <a href=
"http://github.com/Constellation/crxmake">github: crxmake
</a>
103 <h3 id=
"bash">Bash
</h3>
107 # Purpose: Pack a Chromium extension directory into crx format
109 if test $# -ne
2; then
110 echo
"Usage: crxmake.sh <extension dir> <pem path>"
116 name=$(basename
"$dir")
121 trap 'rm -f
"$pub" "$sig" "$zip"' EXIT
125 (cd
"$dir" && zip -qr -
9 -X
"$cwd/$zip" .)
128 openssl sha1 -sha1 -binary -sign
"$key" <
"$zip" > "$sig"
131 openssl rsa -pubout -outform DER <
"$key" > "$pub" 2>/dev/null
134 # Take
"abcdefgh" and return it as
"ghefcdab"
135 echo
"${1:6:2}${1:4:2}${1:2:2}${1:0:2}"
138 crmagic_hex=
"4372 3234" # Cr24
139 version_hex=
"0200 0000" #
2
140 pub_len_hex=$(byte_swap $(printf '%
08x\n' $(ls -l
"$pub" | awk '{print $
5}')))
141 sig_len_hex=$(byte_swap $(printf '%
08x\n' $(ls -l
"$sig" | awk '{print $
5}')))
143 echo
"$crmagic_hex $version_hex $pub_len_hex $sig_len_hex" | xxd -r -p
144 cat
"$pub" "$sig" "$zip"