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