【问题标题】:How to create chrome crx file programmatically (preferably in java)?如何以编程方式创建 chrome crx 文件(最好在 java 中)?
【发布时间】:2011-03-12 21:59:04
【问题描述】:

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

【问题讨论】:

标签: command-line google-chrome crx


【解决方案1】:

正如 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 算法的命令行打包。

【讨论】:

  • 如果您还使用 --no-message-box 选项,该过程将完全静默,适合在脚本中使用。
  • 我的返回码是 21,但周围没有 crx 文件。
  • 你能告诉我输出文件是从哪里来的吗?
  • 您需要在[extension_path] 中包含该版本。该文件在顶级目录中生成。例如命令chrome --pack-extension=/path/to/chrome-profile/Extensions/pehaalcefcjfccdpbckoablngfkfgfgj/1.1_0/path/to/chrome-profile/Extensions/pehaalcefcjfccdpbckoablngfkfgfgj/1.1_0.crx生成文件
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 正是我想要的。谢谢。
  • 我知道这是旧的,但这对我帮助很大!
  • 由于您不再是新用户,您能否使用实际链接更新您的答案?
【解决方案3】:
//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;
    }

【讨论】:

  • 我认为签名和公钥是 crx 可选的,但不是。这是我的解决方案所缺少的难题。
  • 很遗憾,版本 2 crx 不再受支持
【解决方案4】:

我需要在 Ruby 中执行此操作。 JavaHead 的答案对于 CRX2 的 Java 来说看起来不错。当前格式为 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

【讨论】:

    猜你喜欢
    • 2012-07-30
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    相关资源
    最近更新 更多