Create Google Chrome Crx file with PHP
Asked Answered
B

3

5

Id like to be able to generate a crx file with PHP.

A crx file is a zip file with an additional header and Im at a lost on how to create this header. I can create a crx file if I use a pregenerated pem file but this leads to all the crx files having the same extension id and this is not good. Heres a link to what Ive got so far.....
http://valorsolo.com/index.php?page=Viewing%20Message&id=1472&pagenum=2#1500

Incase it helps this has been done in Python and there is an excellent blog post on the finer details here....
http://blog.roomanna.com/12-12-2010/packaging-chrome-extensions
and heres some links to other code on the subject.....
http://code.google.com/chrome/extensions/crx.html
http://code.google.com/p/crx-packaging/source/browse/trunk/packer.py
https://github.com/bellbind/crxmake-python/blob/master/crxmake.py
http://www.curetheitch.com/projects/buildcrx/

Bluet answered 16/2, 2011 at 6:37 Comment(0)
N
3

This ruby code was helpful.

Your public key must be in DER format, and unfortunately PHP's OpenSSL extension can't do that, so far as I can tell. I had to generate it from my private key at the command line:

openssl rsa -pubout -outform DER < extension_private_key.pem > extension_public_key.pub

UPDATE: there is a PHP der2pem() function available here, thanks to tutuDajuju for pointing it out.

Once that's done, building the .crx file is quite easy:

# make a SHA1 signature using our private key
$pk = openssl_pkey_get_private(file_get_contents('extension_private_key.pem'));
openssl_sign(file_get_contents('extension.zip'), $signature, $pk, 'sha1');
openssl_free_key($pk);

# decode the public key
$key = base64_decode(file_get_contents('extension_public_key.pub'));

# .crx package format:
#
#   magic number               char(4)
#   crx format ver             byte(4)
#   pub key lenth              byte(4)
#   signature length           byte(4)
#   public key                 string
#   signature                  string
#   package contents, zipped   string
#
# see http://code.google.com/chrome/extensions/crx.html
#
$fh = fopen('extension.crx', 'wb');
fwrite($fh, 'Cr24');                             // extension file magic number
fwrite($fh, pack('V', 2));                       // crx format version
fwrite($fh, pack('V', strlen($key)));            // public key length
fwrite($fh, pack('V', strlen($signature)));      // signature length
fwrite($fh, $key);                               // public key
fwrite($fh, $signature);                         // signature
fwrite($fh, file_get_contents('extension.zip')); // package contents, zipped
fclose($fh);
Nataline answered 16/2, 2011 at 6:37 Comment(6)
Thanks for your input but that's pretty much what I can do allready. This will sign a zip just fine, but as I stated above all the extensions will have the same extension ID which is far from ideal. Thanks tho.Bluet
Are you sure that's a bad thing? Notice in the manifest file, updates are checked using that very ID. If the ID changed with each build, Chrome would never see any updates to your extension. See code.google.com/chrome/extensions/autoupdate.htmlNataline
since PHP's Open SSL functions use the .pem format, you can use a function to convert from .pem to .der format or visa versa. See: php.net/manual/en/ref.openssl.php#74188. You could also, create a new key on every creation if you wish and then get unique id's. Then, save the keys, get hash of the public key (this should be the ID) and store both to create a dynamic system of creation and update.Elegit
Ah. Thanks for pointing out that pem2der() function! Very useful.Nataline
@JonathonHill This code is not working for me. I used a pem created by Chrome, then generated the ".pub" via your command line code and then used the rest of your code but I get the error: Package is invalid: CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED. Any idea what's wrong?Allegra
Is your public key in DER format? If not, you need to convert it before writing it to the CRX file.Nataline
C
2

The CRX format is described in detail on the documentation page: http://code.google.com/chrome/extensions/crx.html

There are examples on the end of that file for Ruby and Bash. Follow the format in your language (PHP).

Clishmaclaver answered 17/2, 2011 at 3:33 Comment(1)
If I could do that I wouldn't be asking for help ;) But thanks for putting up that link, I forgot that one....and I have read it (many times) it's just a little beyond me.Bluet
R
2

You can use the working PHP solution: https://github.com/andyps/crxbuild There are a PHP class that you can include in your project and command line script.

Readability answered 16/11, 2013 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.