怎么用脚本获取数字签名

wen 实用脚本 2

本文目录导读:

怎么用脚本获取数字签名

  1. 为什么你需要“脚本化”获取数字签名?
  2. 数字签名的核心原理(3分钟速览)
  3. 实战前准备:工具链与权限清单
  4. 方法一:Python + asn1crypto 解析PE文件签名
  5. 方法二:Bash + osslsigncode 提取嵌入式签名
  6. 方法三:调用Windows原生API(PowerShell)
  7. 签名验证与常见坑
  8. 高频问答(FAQ)
  9. 安全与合规提醒

**
《数字签名提取黑科技:手把手教你用脚本自动化获取与验证(附Python/Bash实战)》


目录导读

  1. 为什么你需要“脚本化”获取数字签名?
  2. 数字签名的核心原理(3分钟速览)
  3. 实战前准备:工具链与权限清单
  4. Python + asn1crypto 解析PE文件签名
  5. Bash + osslsigncode 提取嵌入式签名
  6. 调用Windows原生API(PowerShell)
  7. 签名验证与常见坑(时间戳、交叉证书)
  8. 高频问答(FAQ)
  9. 安全与合规提醒

为什么你需要“脚本化”获取数字签名?

在软件供应链安全审计、恶意样本分析或合规取证场景中,分析师常需批量提取Windows可执行文件(PE)、驱动或安装包的数字签名,手动右键属性查看签名,不仅效率低下(尤其面对数百个样本),且无法获取原始签名块(如PKCS#7结构)用于深度验证,脚本化能将提取时间从“分钟级”压缩到“毫秒级”,并输出结构化数据(哈希、颁发者、有效期)供后续自动化比对。

数字签名的核心原理(3分钟速览)

数字签名本质是文件内容的加密摘要,由权威CA(证书颁发机构)私钥生成,Windows PE的签名通常嵌入在PE文件末尾的证书表目录中(IMAGE_DIRECTORY_ENTRY_SECURITY),结构遵循PKCS#7规范,包含签名者证书链、摘要算法(如SHA256)及可选时间戳,脚本提取的关键在于定位证书表偏移,而非单纯读取文件尾部——因为签名数据可能比文件对齐填充更短。

实战前准备:工具链与权限清单

  • Python环境:3.8+,安装pefileasn1cryptopip install pefile asn1crypto)。
  • OpenSSL工具:需1.1.1+版本,用于解析PKCS#7。
  • Windows系统:PowerShell 5.1+(自带System.Security.Cryptography)。
  • 权限:读取文件无需管理员权限,但如需解析系统受保护文件(如C:\Windows\System32下的驱动),需提升至管理员。

    注意:脚本仅提取签名,不会修改文件,但请确保操作副本以防意外。

方法一:Python + asn1crypto 解析PE文件签名

pefile库能直接暴露安全目录入口,配合asn1crypto可解包签名详情,以下脚本提取签名原始字节并转储为DER文件:

import pefile  
from asn1crypto import cms  
def extract_pe_signature(file_path):
    pe = pefile.PE(file_path)
    if not hasattr(pe, 'DIRECTORY_ENTRY_SECURITY'):
        print("No signature found.")
        return None
    # 获取证书表偏移和长度
    sec_entry = pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']]
    with open(file_path, 'rb') as f:
        f.seek(sec_entry.VirtualAddress)
        sig_data = f.read(sec_entry.Size)
    # 解析PKCS#7签名
    content_info = cms.ContentInfo.load(sig_data)
    signed_data = content_info['content']
    signer_info = signed_data['signer_infos'][0]
    issuer = signer_info['sid'].chosen
    print(f"Issuer: {issuer.human_friendly}")
    print(f"Digest Algorithm: {signer_info['digest_algorithm']['algorithm'].native}")
    return sig_data  # 保存为.der即可

关键点VirtualAddress指向签名起始位置,而签名数据可能包含多个证书,需遍历certificates字段获取完整链。

方法二:Bash + osslsigncode 提取嵌入式签名

osslsigncode(开源替代signtool)支持从PE提取签名到独立文件:

# 安装:sudo apt install osslsigncode 或 brew install osslsigncode  
# 提取签名到signature.der  
osslsigncode extract-signature -in app.exe -out signature.der  
# 查看签名详细信息(含时间戳)  
osslsigncode verify -in app.exe -print  

优势:无需编程,适合单文件快速验证。局限:无法批量处理,需配合循环。

方法三:调用Windows原生API(PowerShell)

PowerShell可调用Authenticode签名对象,直接输出签名状态及证书链:

$filePath = "C:\path\to\app.exe"  
$signature = Get-AuthenticodeSignature $filePath  
if ($signature.Status -eq "Valid") {  
    $cert = $signature.SignerCertificate  
    Write-Host "Signed by: $($cert.Subject)"  
    Write-Host "Expires: $($cert.NotAfter)"  
} else {  
    Write-Host "Signature invalid: $($signature.StatusMessage)"  
}  

扩展:通过Get-ChildItem递归遍历目录,实现批量检测,此方法不提取原始字节,但适合快速合规检查。

签名验证与常见坑

  • 时间戳问题:若签名无时间戳,文件在证书过期后将视为无效,提取时需检查signing_time属性。
  • 交叉证书:部分签名链包含中间证书,脚本需收集所有证书并建立信任链(可借助系统证书库)。
  • 截断签名:某些恶意样本伪造签名表头部,始终验证Size是否与实际读取长度一致,并用openssl asn1parse检查DER结构完整性。

高频问答(FAQ)

Q1:脚本提取的签名与右键属性看到的“数字签名”是否相同?
A:相同,右键属性显示的是签名验证后的摘要信息,而脚本提取的是原始二进制数据(PKCS#7),后者包含完整证书链,更适合离线审计。

Q2:无签名文件会报错吗?
A:脚本需处理NotSigned异常,建议先调用pefile检查安全目录是否存在,再执行提取。

Q3:如何获取签名的SHA256哈希?
A:对提取的DER字节直接计算hashlib.sha256(sig_data).hexdigest()即可。

Q4:脚本能否用于macOS或Linux的二进制签名?
A:不能,macOS使用类似codesign的Mach-O签名格式;Linux通常无强制签名,但可提取嵌入的PKCS#7,只要容器是PE。

安全与合规提醒

  • 仅对合法拥有的文件执行提取操作,解析恶意样本时,请使用隔离虚拟机或沙箱,防止触发行为。
  • 提取的原始签名可能包含个人身份信息(如组织名称),存储时需脱敏或加密。
  • 若用于法律取证,请保留SHA256哈希链及提取时间,确保证据可追溯性。


通过脚本化手段,你将不再依赖图形界面,实现数字签名的批量提取、解析与验证,无论是构建病毒库指纹,还是检查内部软件合规,这套方法都能成为你工具箱中的利刃,现在即可从Python脚本开始,逐步扩展到自动化流水线,让签名数据为你所用。

抱歉,评论功能暂时关闭!