如何以编程方式计算Chrome扩展ID?

问题描述 投票:7回答:3

我正在构建一个自动化流程来生成扩展。是否存在直接计算扩展ID并完全绕过与浏览器交互的代码示例?

(我在回答我自己的问题,下面。)

python google-chrome google-chrome-extension sha256
3个回答
9
投票

我只能找到一篇关于Ruby片段的相关文章,它只能在IA中找到:http://web.archive.org/web/20120606044635/http://supercollider.dk/2010/01/calculating-chrome-extension-id-from-your-private-key-233

重要的是要知道:

  1. 这取决于DER编码的公钥(原始二进制),而不是PEM编码的密钥(通过base64编码DER密钥生成的漂亮ASCII)。
  2. 扩展ID是base-16,但是使用[a-p](称为“mpdecimal”)而不是[0-9a-f]进行编码。

使用PEM编码的公钥,请按照以下步骤操作:

  1. 如果您的PEM格式的公钥仍然具有页眉和页脚并分成多行,请手动重新格式化,以便您有一个字符串排除页眉和页脚,并一起运行,使得每一行密钥包装到下一个。
  2. Base64-解码公钥以呈现DER格式的公钥。
  3. 生成DER格式密钥的SHA256十六进制摘要。
  4. 取哈希的前32个字节。你不需要其余的。
  5. 对于每个字符,将其转换为base-10,并为“a”添加ASCII代码。

以下是执行此操作的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格式的公钥:

  1. 进入Chrome中现有扩展程序的列表。获取一个扩展ID。
  2. 找到托管扩展的目录。在我的Windows 7框中,它是:C:\ Users \\ AppData \ Local \ Google \ Chrome \ User Data \ Default \ Extensions \
  3. 从“key”下的manifest.json文件中获取公钥。由于密钥已准备好进行base64解码,因此可以跳过该过程的步骤(1)。

示例中的公钥来自“Chrome阅读器”扩展程序。它的扩展ID是“lojpenhmoajbiciapkjkiekmobleogjc”。

也可以看看:

  1. Google Chrome - Alphanumeric hashes to identify extensions
  2. http://blog.roomanna.com/12-14-2010/getting-an-extensions-id

5
投票

从Chrome 64开始,Chrome更改了CRX₃ file format扩展的包格式,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\0\0\0\3' 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() 支持多个签名并明确声明其CRX ID。从CRX 3文件中提取CRX ID需要解析协议缓冲区。

这是一个小的python脚本,用于从CRX 3文件中提取ID。此解决方案应仅用于受信任的CRX 3文件或在不担心安全性的上下文中:与CRX 2不同,包格式不限制CRX 3文件声明的CRX ID。 (实际上,文件的消费者(即Chrome)会对其施加限制,例如要求使用至少一个散列到声明的CRX ID的密钥对文件进行签名)。

https://github.com/thelinuxkid/python-protolite

(感谢http://developer.chrome.com/extensions/crx.html的protobuf解析器骨架。)


3
投票

使用python从.crx文件获取公钥的一种简单方法,因为chrome只会为您生成私有.pem密钥。公钥实际存储在.crx文件中。

这是基于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

虽然这不可能“绕过与浏览器的交互”,因为您仍然需要使用类似命令生成.crx文件

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.