如何以编程方式创建chrome crx文件(最好是在java)?

时间:2010-07-07 16:03:33

标签: command-line google-chrome crx

我想以编程方式创建chrome扩展crx文件(不使用chrome.exe,因为它会打开新的chrome窗口)。那么有什么替代方案呢?我的偏好是java,但如果它可能用其他语言,那么我也没关系。

4 个答案:

答案 0 :(得分:23)

正如kylehuff所说,你可以使用外部工具。但您始终可以使用Google Chrome中的命令行执行跨平台命令行(Linux / Windows / Mac)。

chrome.exe --pack-extension=[extension_path] --pack-extension-key=[extension_key]

- pack-extension 是:

  

将扩展名打包到给定目录中的.crx可安装文件。

- pack-extension-key 是:

  

可选的PEM私钥用于签名打包的.crx。

上面没有运行谷歌浏览器,它只是使用他们内部使用的Chromium核心crx算法的命令行打包。

答案 1 :(得分:13)

有各种各样的实用程序可以用各种语言来实现(尽管它们主要是shell /脚本语言)

我无法发布所有链接,因为我是一个新的stackoverflow用户 - 我只能发布1个链接,所以我创建了一个列出所有链接的页面 - 包括我在下面谈到的那个C - {{{ 3}}

无论如何,我花了几个小时在C或Windows上运行一个版本,因为其他解决方案需要安装脚本语言或shell(即python,ruby,bash等)和OpenSSL。我编写的实用程序具有静态链接的OpenSSL,因此没有解释器或库要求。

存储库托管在github上,但上面的链接列出了我的实用程序和其他人的解决方案。

没有为Java列出任何内容,这是您的偏好,但希望这有帮助!

答案 2 :(得分:2)

//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;
    }

答案 3 :(得分:0)

我需要在Ruby中执行此操作。对于CRX2的Java,JavaHead的答案看起来不错。当前格式为CRX v3,标头基于protobuf。我写了一个blog,用于将扩展与Ruby打包在一起。还有另一位作者的python project

我将粘贴Ruby版本的CRX2和CRX3方法来打包扩展,以供此处参考。有关完整的代码,请参见我的博客。

那么CRX3方法:

 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

出于历史目的(已通过验证),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

我使用了出色的服务crx-checker来验证-v2和v3扩展打包。我在哪里得到标记为RSASSA-PKCS1-v1_5的预期(Signature OK) (Developer Signature)签名。

如果您尝试从URL添加到浏览器,则扩展名将无法加载CRX_REQUIRED_PROOF_MISSING,因为该扩展名缺少Google签名。但是运行测试时,它会被Selenium很好地加载。要正常加载,您需要在网上商店上publish