我想以编程方式创建 chrome 扩展 crx 文件(不使用 chrome.exe,因为它会打开新的 chrome 窗口)。那么相同的替代方案是什么?我的偏好是java,但如果它可能用其他语言,那么我也可以。
4 回答
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.
有多种实用程序可以使用各种语言来执行此操作(尽管它们主要是 shell/脚本语言)
我无法发布所有链接,因为我是一个新的 stackoverflow 用户 - 我只能发布 1 个链接,所以我创建了一个列出所有链接的页面 - 包括我在下面谈到的一个 C - http://curetheitch .com/projects/buildcrx/6/
无论如何,我花了几个小时在 C 中编写了一个在 Windows 或 Linux 上运行的版本,因为其他解决方案需要安装脚本语言或 shell(即 python、ruby、bash 等)和 OpenSSL。我编写的实用程序具有静态链接的 OpenSSL,因此没有解释器或库要求。
该存储库托管在 github 上,但上面的链接列出了我的实用程序和其他人的解决方案。
Java 没有列出任何内容,这是您的偏好,但希望对您有所帮助!
//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;
}
我需要在 Ruby 中执行此操作。JavaHead 的答案对于 CRX2 的 Java 来说看起来不错。当前格式是 CRX v3,并且标头是基于protobuf的。我写了一个博客来用 Ruby 打包一个扩展。还有一个来自另一位作者的python 项目。
我将在此处粘贴用于打包扩展的 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 很好地加载。要正常加载,您需要在网上商店发布。