I'm building an automated process to produce extensions. Is there a code example of calculating the extension-ID directly and entirely bypassing interaction with the browser?
(I'm answering my own question, below.)
I'm building an automated process to produce extensions. Is there a code example of calculating the extension-ID directly and entirely bypassing interaction with the browser?
(I'm answering my own question, below.)
我只能找到一篇带有 Ruby 片段的相关文章,而且它只在 IA 中可用:http://web.archive.org/web/20120606044635/http: //supercollider.dk/2010/01/calculating- chrome-extension-id-from-your-private-key-233
重要的是要知道:
使用 PEM 编码的公钥,执行以下步骤:
以下是执行此操作的 Python 例程:
import hashlib
from base64 import b64decode
def build_id(pub_key_pem):
pub_key_der = b64decode(pub_key_pem)
sha = hashlib.sha256(pub_key_der).hexdigest()
prefix = sha[:32]
reencoded = ""
ord_a = ord('a')
for old_char in prefix:
code = int(old_char, 16)
new_char = chr(ord_a + code)
reencoded += new_char
return reencoded
def main():
pub_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjvF5pjuK8gRaw/2LoRYi37QqRd48B/FeO9yFtT6ueY84z/u0NrJ/xbPFc9OCGBi8RKIblVvcbY0ySGqdmp0QsUr/oXN0b06GL4iB8rMhlO082HhMzrClV8OKRJ+eJNhNBl8viwmtJs3MN0x9ljA4HQLaAPBA9a14IUKLjP0pWuwIDAQAB'
id_ = build_id(pub_key)
print(id_)
if __name__ == '__main__':
main()
非常欢迎您针对现有扩展及其 ID 进行测试。要检索其 PEM 格式的公钥:
示例中的公钥来自“Chrome Reader”扩展。它的扩展 ID 是“lojpenhmoajbciapkjkiekmobleogjc”。
也可以看看:
从 Chrome 64 开始,Chrome 将扩展的包格式更改为CRX₃ 文件格式,该格式支持多个签名并明确声明其 CRX ID。从 CRX₃ 文件中提取 CRX ID 需要解析协议缓冲区。
这是一个用于从 CRX₃ 文件中提取 ID 的小型 Python 脚本。此解决方案应仅用于受信任的 CRX₃ 文件或在不考虑安全性的情况下:与 CRX₂ 不同,包格式不限制 CRX₃ 文件声明的 CRX ID。(在实践中,文件的使用者(即 Chrome)会对其施加限制,例如要求文件使用至少一个散列到声明的 CRX ID 的密钥进行签名)。
import binascii
import string
import struct
import sys
def decode(proto, data):
index = 0
length = len(data)
msg = dict()
while index < length:
item = 128
key = 0
left = 0
while item & 128:
item = data[index]
index += 1
value = (item & 127) << left
key += value
left += 7
field = key >> 3
wire = key & 7
if wire == 0:
item = 128
num = 0
left = 0
while item & 128:
item = data[index]
index += 1
value = (item & 127) << left
num += value
left += 7
continue
elif wire == 1:
index += 8
continue
elif wire == 2:
item = 128
_length = 0
left = 0
while item & 128:
item = data[index]
index += 1
value = (item & 127) << left
_length += value
left += 7
last = index
index += _length
item = data[last:index]
if field not in proto:
continue
msg[proto[field]] = item
continue
elif wire == 5:
index += 4
continue
raise ValueError(
'invalid wire type: {wire}'.format(wire=wire)
)
return msg
def get_extension_id(crx_file):
with open(crx_file, 'rb') as f:
f.read(8); # 'Cr24\3\0\0\0'
data = f.read(struct.unpack('<I', f.read(4))[0])
crx3 = decode(
{10000: "signed_header_data"},
[ord(d) for d in data])
signed_header = decode(
{1: "crx_id"},
crx3['signed_header_data'])
return string.translate(
binascii.hexlify(bytearray(signed_header['crx_id'])),
string.maketrans('0123456789abcdef', string.ascii_lowercase[:16]))
def main():
if len(sys.argv) != 2:
print 'usage: %s crx_file' % sys.argv[0]
else:
print get_extension_id(sys.argv[1])
if __name__ == "__main__":
main()
(感谢https://github.com/thelinuxkid/python-protolite的 protobuf 解析器框架。)
使用 python 从 .crx 文件中获取公钥的一种简单而简单的方法,因为 chrome 只会为您生成私有 .pem 密钥。公钥实际上存储在 .crx 文件中。
这是基于此处找到的 .crx 文件的格式http://developer.chrome.com/extensions/crx.html
import struct
import hashlib
import string
def get_pub_key_from_crx(crx_file):
with open(crx_file, 'rb') as f:
data = f.read()
header = struct.unpack('<4sIII', data[:16])
pubkey = struct.unpack('<%ds' % header[2], data[16:16+header[2]])[0]
return pubkey
def get_extension_id(crx_file):
pubkey = get_pub_key_from_crx(crx_file)
digest = hashlib.sha256(pubkey).hexdigest()
trans = string.maketrans('0123456789abcdef', string.ascii_lowercase[:16])
return string.translate(digest[:32], trans)
if __name__ == '__main__':
import sys
if len(sys.argv) != 2:
print 'usage: %s crx_file' % sys.argv[0]
print get_extension_id(sys.argv[1])
虽然这不可能做到“绕过与浏览器的交互”,因为您仍然需要使用类似的命令生成 .crx 文件
chrome.exe --pack-extension=my_extension --pack-extension-key=my_extension.pem