I want to create chrome extension crx file programatically (not using chrome.exe, because it opens new chrome window). So what are the alternatives for same ? My preference is java, but if its possible in other language then also I am okay.
-
I had a similar problem , here is the solution: http://stackoverflow.com/questions/24661167/generating-chrome-packaged-app-crx-header-with-java/24675290#24675290 – JavaHead Jul 11 '14 at 03:30
4 Answers
As kylehuff stated, there are external tools that you could use. But you can always use the command line from Google Chrome to do that which is cross platform (Linux / Windows / Mac).
chrome.exe --pack-extension=[extension_path] --pack-extension-key=[extension_key]
--pack-extension is:
Package an extension to a .crx installable file from a given directory.
--pack-extension-key is:
Optional PEM private key is to use in signing packaged .crx.
The above does not run Google Chrome, it is just command line packing using Chromium's core crx algorithm that they use internally.

- 39,445
- 10
- 116
- 90
-
10If you also use the --no-message-box option the process will be completely silent, suitable for use in a script. – Marten Oct 31 '11 at 10:06
-
1
-
2
-
You need to include the version in `[extension_path]`. The file is generated in the top level directory. For example the command `chrome --pack-extension=/path/to/chrome-profile/Extensions/pehaalcefcjfccdpbckoablngfkfgfgj/1.1_0` generates the file at `/path/to/chrome-profile/Extensions/pehaalcefcjfccdpbckoablngfkfgfgj/1.1_0.crx` – Johannes Barop Nov 29 '18 at 14:50
There is a variety of utilities to do this, in various languages (albeit; they are mostly shell/scripting languages)
I cannot post the links to all of them, because I am a new stackoverflow user - I can only post 1 link, so I created a page which lists them all - including the one C one I speak about below - http://curetheitch.com/projects/buildcrx/6/
Anyway, I spent a few hours and put together a version in C which runs on Windows or Linux, as the other solutions require installation of a scripting language or shell (i.e. python, ruby, bash, etc.) and OpenSSL. The utility I wrote has OpenSSL statically linked so there are no interpreter or library requirements.
The repository is hosted on github, but the link above has a list of my utility and other peoples solutions.
Nothing listed for Java, which was your preference, but hopefully that helps!

- 5,177
- 2
- 34
- 35
-
-
6Can you update your answer with the actual links seeing as you are no longer a new user? – Mihai Danila Aug 22 '13 at 16:09
//Method to generate .crx. signature
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Signature;
//@param : extenstionContents is your zip file ,
//@returns : byte[] of the signature , use ByteBuffer to merge them and you have your
// .crx
public static byte[] generateCrxHeader(byte[] extensionContents) throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
Signature sigInstance = Signature.getInstance("SHA1withRSA");
sigInstance.initSign(pair.getPrivate());
sigInstance.update(extensionContents);
byte [] signature = sigInstance.sign();
byte [] subjectPublicKeyInfo = pair.getPublic().getEncoded();
final int headerLength = 4 + 4 + 4 + 4 + subjectPublicKeyInfo.length + signature.length;
ByteBuffer headerBuf = ByteBuffer.allocate(headerLength);
headerBuf.order(ByteOrder.LITTLE_ENDIAN);
headerBuf.put(new byte[]{0x43,0x72,0x32,0x34}); // Magic number
headerBuf.putInt(2); // Version
headerBuf.putInt(subjectPublicKeyInfo.length); // public key length
headerBuf.putInt(signature.length); // signature length
headerBuf.put(subjectPublicKeyInfo);
headerBuf.put(signature);
final byte [] header = headerBuf.array();
return header;
}

- 635
- 1
- 6
- 21
-
I thought signature and public key are optional by crx, but not. That was missing puzzle for my solution. – San Droid Nov 04 '16 at 17:04
-
I needed to do this in Ruby. JavaHead's answer looks nice for Java for CRX2. The current format is CRX v3 and header is protobuf based. I wrote a blog for packing an extension with Ruby. There is also a python project from another author.
I'll paste Ruby version of CRX2 and CRX3 methods for packing extensions for a reference here. For complete code see my blog.
So CRX3 method:
def self.header_v3_extension(zipdata, key: nil)
key ||= OpenSSL::PKey::RSA.generate(2048)
digest = OpenSSL::Digest.new('sha256')
signed_data = Crx_file::SignedData.new
signed_data.crx_id = digest.digest(key.public_key.to_der)[0...16]
signed_data = signed_data.encode
signature_data = String.new(encoding: "ASCII-8BIT")
signature_data << "CRX3 SignedData\00"
signature_data << [ signed_data.size ].pack("V")
signature_data << signed_data
signature_data << zipdata
signature = key.sign(digest, signature_data)
proof = Crx_file::AsymmetricKeyProof.new
proof.public_key = key.public_key.to_der
proof.signature = signature
header_struct = Crx_file::CrxFileHeader.new
header_struct.sha256_with_rsa = [proof]
header_struct.signed_header_data = signed_data
header_struct = header_struct.encode
header = String.new(encoding: "ASCII-8BIT")
header << "Cr24"
header << [ 3 ].pack("V") # version
header << [ header_struct.size ].pack("V")
header << header_struct
return header
end
And for historic purposes (this one verified) CRX2:
# @note original crx2 format description https://web.archive.org/web/20180114090616/https://developer.chrome.com/extensions/crx
def self.header_v2_extension(zipdata, key: nil)
key ||= OpenSSL::PKey::RSA.generate(2048)
digest = OpenSSL::Digest.new('sha1')
header = String.new(encoding: "ASCII-8BIT")
signature = key.sign(digest, zipdata)
signature_length = signature.length
pubkey_length = key.public_key.to_der.length
header << "Cr24"
header << [ 2 ].pack("V") # version
header << [ pubkey_length ].pack("V")
header << [ signature_length ].pack("V")
header << key.public_key.to_der
header << signature
return header
end
I have used the excellent service crx-checker to validate both - v2 and v3 extension packing. Where I'm getting the expected RSASSA-PKCS1-v1_5
signature marked (Signature OK) (Developer Signature)
.
The extension will fail to load with CRX_REQUIRED_PROOF_MISSING
if you try to add to your browser from URL because it will be lacking Google signature. But it will be loaded fine by Selenium when running test. To load normally you need to publish on web store.

- 17,364
- 6
- 77
- 85