1 <div id="pageData-name" class="pageData">CRX Package Format</div> 2 <div id="pageData-showTOC" class="pageData">true</div> 3 4 <p> 5 CRX files are ZIP files with a special header and the <code>.crx</code> file 6 extension. 7 </p> 8 9 <h2>Package header</h2> 10 11 <p> 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: 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> 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 71 was generated from. 72 </p> 73 74 <h2>Example</h2> 75 76 <p> 77 The following is an example hex dump from the beginning of a <code>.crx</code> 78 file. 79 </p> 80 81 <pre> 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 89 90 </pre> 91 92 <h2 id="scripts">Packaging scripts</h2> 93 <p> 94 Members 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 109 if test $# -ne 2; then 110 echo "Usage: crxmake.sh <extension dir> <pem path>" 111 exit 1 112 fi 113 114 dir=$1 115 key=$2 116 name=$(basename "$dir") 117 crx="$name.crx" 118 pub="$name.pub" 119 sig="$name.sig" 120 zip="$name.zip" 121 trap 'rm -f "$pub" "$sig" "$zip"' EXIT 122 123 # zip up the crx dir 124 cwd=$(pwd -P) 125 (cd "$dir" && zip -qr -9 -X "$cwd/$zip" .) 126 127 # signature 128 openssl sha1 -sha1 -binary -sign "$key" < "$zip" > "$sig" 129 130 # public key 131 openssl rsa -pubout -outform DER < "$key" > "$pub" 2>/dev/null 132 133 byte_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 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}'))) 142 ( 143 echo "$crmagic_hex $version_hex $pub_len_hex $sig_len_hex" | xxd -r -p 144 cat "$pub" "$sig" "$zip" 145 ) > "$crx" 146 echo "Wrote $crx" 147 </pre> 148 149