1<div id="pageData-name" class="pageData">CRX Package Format</div> 2<div id="pageData-showTOC" class="pageData">true</div> 3 4<p> 5CRX files are ZIP files with a special header and the <code>.crx</code> file 6extension. 7</p> 8 9<h2>Package header</h2> 10 11<p> 12The header contains the author's public key and the extension's signature. 13The signature is generated from the ZIP file using SHA-1 with the 14author's private key. The header requires a little-endian byte ordering with 154-byte alignment. The following table describes the fields of 16the <code>.crx</code> header in order: 17</p> 18 19<table> 20 <tr> 21 <th>Field</th><th>Type</th><th>Length</th><th>Value</th><th>Description</th> 22 </tr> 23 <tr> 24 <td><em>magic number</em></td><td>char[]</td><td>32 bits</td><td>Cr24</td> 25 <td> 26 Chrome requires this constant at the beginning of every <code>.crx</code> 27 package. 28 </td> 29 </tr> 30 <tr> 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> 33 </tr> 34 <tr> 35 <td><em>public key length</em></td><td>unsigned int</td><td>32 bits</td> 36 <td><i>pubkey.length</i></td> 37 <td> 38 The length of the RSA public key in <em>bytes</em>. 39 </td> 40 </tr> 41 <tr> 42 <td><em>signature length</em></td><td>unsigned int</td><td>32 bits</td> 43 <td><i>sig.length</i></td> 44 <td> 45 The length of the signature in <em>bytes</em>. 46 </td> 47 </tr> 48 <tr> 49 <td><em>public key</em></td><td>byte[]</td><td><i>pubkey.length</i></i></td> 50 <td><i>pubkey.contents</i></td> 51 <td> 52 The contents of the author's RSA public key, formatted as an X509 53 SubjectPublicKeyInfo block. 54 </td> 55 </tr> 56 <tr> 57 <td><em>signature</em></td><td>byte[]</td><td><i>sig.length</i></td> 58 <td><i>sig.contents</i></td> 59 <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. 62 </td> 63 </tr> 64</table> 65 66<h2>Extension contents</h2> 67 68<p> 69The extension's ZIP file is appended to the <code>*.crx</code> package after the 70header. This should be the same ZIP file that the signature in the header 71was generated from. 72</p> 73 74<h2>Example</h2> 75 76<p> 77The following is an example hex dump from the beginning of a <code>.crx</code> 78file. 79</p> 80 81<pre> 8243 72 32 34 # "Cr24" -- the magic number 8302 00 00 00 # 2 -- the crx format version number 84A2 00 00 00 # 162 -- length of public key in bytes 8580 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 89 90</pre> 91 92<h2 id="scripts">Packaging scripts</h2> 93<p> 94Members of the community have written the following scripts to package 95<code>.crx</code> files. 96</p> 97 98<h3 id="ruby">Ruby</h3> 99<blockquote> 100<a href="http://github.com/Constellation/crxmake">github: crxmake</a> 101</blockquote> 102 103<h3>Bash</h3> 104<pre> 105#!/bin/bash -e 106# 107# Purpose: Pack a Chromium extension directory into crx format 108 109if test $# -ne 2; then 110 echo "Usage: crxmake.sh <extension dir> <pem path>" 111 exit 1 112fi 113 114dir=$1 115key=$2 116name=$(basename "$dir") 117crx="$name.crx" 118pub="$name.pub" 119sig="$name.sig" 120zip="$name.zip" 121trap 'rm -f "$pub" "$sig" "$zip"' EXIT 122 123# zip up the crx dir 124cwd=$(pwd -P) 125(cd "$dir" && zip -qr -9 -X "$cwd/$zip" .) 126 127# signature 128openssl sha1 -sha1 -binary -sign "$key" < "$zip" > "$sig" 129 130# public key 131openssl rsa -pubout -outform DER < "$key" > "$pub" 2>/dev/null 132 133byte_swap () { 134 # Take "abcdefgh" and return it as "ghefcdab" 135 echo "${1:6:2}${1:4:2}${1:2:2}${1:0:2}" 136} 137 138crmagic_hex="4372 3234" # Cr24 139version_hex="0200 0000" # 2 140pub_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$pub" | awk '{print $5}'))) 141sig_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$sig" | awk '{print $5}'))) 142( 143 echo "$crmagic_hex $version_hex $pub_len_hex $sig_len_hex" | xxd -r -p 144 cat "$pub" "$sig" "$zip" 145) > "$crx" 146echo "Wrote $crx" 147</pre> 148 149