103 lines
3.0 KiB
Python
103 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
为 plugin-loader 插件签名
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
import base64
|
|
import hashlib
|
|
import time
|
|
from pathlib import Path
|
|
|
|
from cryptography.hazmat.primitives import hashes, serialization
|
|
from cryptography.hazmat.primitives.asymmetric import padding
|
|
from cryptography.hazmat.backends import default_backend
|
|
|
|
# ========== 配置 ==========
|
|
PROJECT_ROOT = Path(__file__).parent.parent
|
|
PRIVATE_KEY_FILE = PROJECT_ROOT / "data" / "signature-verifier" / "keys" / "private" / "futureoss_private.pem"
|
|
PLUGIN_DIR = PROJECT_ROOT / "store" / "@{FutureOSS}" / "plugin-loader"
|
|
|
|
|
|
def compute_plugin_hash(plugin_dir: Path) -> str:
|
|
"""计算插件目录的内容哈希"""
|
|
hasher = hashlib.sha256()
|
|
files_to_hash = []
|
|
for file_path in sorted(plugin_dir.rglob("*")):
|
|
if file_path.is_file() and file_path.name != "SIGNATURE":
|
|
rel_path = file_path.relative_to(plugin_dir)
|
|
files_to_hash.append((str(rel_path), file_path))
|
|
|
|
for rel_path, file_path in files_to_hash:
|
|
hasher.update(rel_path.encode("utf-8"))
|
|
hasher.update(file_path.read_bytes())
|
|
|
|
return hasher.hexdigest()
|
|
|
|
|
|
def sign_plugin():
|
|
"""为插件签名"""
|
|
# 加载私钥
|
|
print(f"加载私钥: {PRIVATE_KEY_FILE}")
|
|
private_key = serialization.load_pem_private_key(
|
|
PRIVATE_KEY_FILE.read_bytes(),
|
|
password=None,
|
|
backend=default_backend()
|
|
)
|
|
|
|
# 计算插件哈希
|
|
print(f"计算插件目录哈希...")
|
|
plugin_hash = compute_plugin_hash(PLUGIN_DIR)
|
|
print(f"哈希: {plugin_hash}")
|
|
|
|
# 签名
|
|
signed_data = f"FutureOSS:{plugin_hash}".encode("utf-8")
|
|
signature = private_key.sign(
|
|
signed_data,
|
|
padding.PSS(
|
|
mgf=padding.MGF1(hashes.SHA256()),
|
|
salt_length=padding.PSS.MAX_LENGTH
|
|
),
|
|
hashes.SHA256()
|
|
)
|
|
|
|
# 写入签名文件
|
|
sig_data = {
|
|
"signature": base64.b64encode(signature).decode(),
|
|
"signer": "FutureOSS",
|
|
"algorithm": "RSA-SHA256",
|
|
"timestamp": time.time(),
|
|
"plugin_hash": plugin_hash,
|
|
"author": "FutureOSS"
|
|
}
|
|
|
|
signature_file = PLUGIN_DIR / "SIGNATURE"
|
|
signature_file.write_text(json.dumps(sig_data, indent=2))
|
|
print(f"\n✓ 签名成功!")
|
|
print(f" 插件: {PLUGIN_DIR.name}")
|
|
print(f" 签名文件: {signature_file}")
|
|
print(f" 算法: RSA-SHA256")
|
|
print(f" 时间戳: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
from cryptography.hazmat.primitives import hashes, serialization
|
|
from cryptography.hazmat.primitives.asymmetric import padding
|
|
from cryptography.hazmat.backends import default_backend
|
|
except ImportError:
|
|
print("错误: 未安装 cryptography 库")
|
|
print("运行: pip install cryptography")
|
|
sys.exit(1)
|
|
|
|
if not PLUGIN_DIR.exists():
|
|
print(f"错误: 插件目录不存在: {PLUGIN_DIR}")
|
|
sys.exit(1)
|
|
|
|
if not PRIVATE_KEY_FILE.exists():
|
|
print(f"错误: 私钥文件不存在: {PRIVATE_KEY_FILE}")
|
|
sys.exit(1)
|
|
|
|
sign_plugin()
|