You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在非macOS环境提取macOS应用CDhash以实现手动公证盖章

跨平台提取macOS应用CDhash的Python实现

CDHash生成规则

CDHash本质是对macOS应用签名中的CodeDirectory结构(ASN.1编码的二进制数据)计算SHA-256哈希,取哈希值的前8字节(对应16个小写十六进制字符)。

跨平台实现方案

通过解析Mach-O二进制文件中的代码签名段,提取CodeDirectory并计算哈希,全程使用纯Python库,不依赖任何macOS专属工具。

依赖安装

pip install asn1crypto macholib

实现代码

import hashlib
import plistlib
from macholib.MachO import MachO
from asn1crypto import cms

def extract_cdhash_from_macho(macho_file_path):
    # 解析Mach-O文件,定位代码签名段
    macho = MachO(macho_file_path)
    signature_bytes = None
    for header in macho.headers:
        for cmd_tuple in header.commands:
            load_cmd = cmd_tuple[0]
            # LC_CODE_SIGNATURE 的命令码是 0x1d
            if load_cmd.cmd == 0x1d:
                signature_bytes = cmd_tuple[1]
                break
        if signature_bytes:
            break
    if not signature_bytes:
        raise ValueError("未在Mach-O文件中找到代码签名")
    
    # 解析CMS签名结构
    content_info = cms.ContentInfo.load(signature_bytes)
    signed_data = content_info.native['content']
    
    # 遍历签名信息,定位CodeDirectory(OID: 1.2.840.113635.100.6.1.25)
    for signer_info in signed_data['signer_infos']:
        for attr in signer_info['signed_attrs']:
            if attr['type'] == '1.2.840.113635.100.6.1.25':
                cd_der_data = attr['values'][0]
                # 计算SHA-256哈希,取前8字节转小写十六进制
                cd_hash = hashlib.sha256(cd_der_data).digest()[:8]
                return cd_hash.hex().lower()
    raise ValueError("未在签名中找到CodeDirectory结构")

def extract_cdhash_from_app(app_bundle_path):
    # 从.app包中读取Info.plist,定位主二进制文件
    info_plist_path = f"{app_bundle_path}/Contents/Info.plist"
    with open(info_plist_path, 'rb') as plist_file:
        info_plist = plistlib.load(plist_file)
    exec_name = info_plist['CFBundleExecutable']
    macho_path = f"{app_bundle_path}/Contents/MacOS/{exec_name}"
    return extract_cdhash_from_macho(macho_path)

# 示例用法
if __name__ == "__main__":
    import sys
    if len(sys.argv) != 2:
        print(f"使用方式: {sys.argv[0]} <应用包路径或Mach-O文件路径>")
        sys.exit(1)
    target = sys.argv[1]
    try:
        if target.endswith('.app'):
            cdhash = extract_cdhash_from_app(target)
        else:
            cdhash = extract_cdhash_from_macho(target)
        print(f"CDHash: {cdhash}")
    except Exception as e:
        print(f"错误: {str(e)}")
        sys.exit(1)

验证方式

在macOS上可通过官方命令对比结果:

codesign -d -vvv MyApp.app | grep CDHash

脚本输出的CDHash应与官方命令结果完全一致。

跨平台支持

  • 依赖库asn1crypto和macholib均为纯Python实现,可在Linux、macOS、Windows等平台正常运行
  • 全程不调用任何macOS专属工具,完全符合跨平台CI场景需求

内容的提问来源于stack exchange,提问作者umläute

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:01:02