fix: 凭证解密优先用 node crypto-helper.js (BWENC1 格式)

secrets.enc 由 crypto-helper.js 加密(BWENC1 格式),
openssl 命令行无法解密(报 bad magic number)。
三个脚本统一修复: 优先 node crypto-helper.js, 回退 openssl。

影响: auto-setup.ps1 / Bookworm-Setup.sh / Bookworm-OneClick-Mac.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
bookworm 2026-04-06 15:04:02 +08:00
parent 67412b871b
commit b4d3f4de24
3 changed files with 46 additions and 7 deletions

View File

@ -239,16 +239,29 @@ $k=$v"
success "凭证已缓存至今日 23:59 (下次免密)" || true success "凭证已缓存至今日 23:59 (下次免密)" || true
} }
# 解密工具: 优先 node crypto-helper.js (BWENC1 格式), 回退 openssl
CRYPTO_HELPER="$BOOT_DIR/crypto-helper.js"
_do_decrypt() {
local pass="$1" enc="$2"
if command -v node &>/dev/null && [ -f "$CRYPTO_HELPER" ]; then
node "$CRYPTO_HELPER" decrypt "$pass" "$enc" 2>/dev/null
elif [ -n "$OPENSSL_CMD" ]; then
$OPENSSL_CMD enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in "$enc" -pass pass:"$pass" 2>/dev/null
else
return 1
fi
}
# 解密凭证 (先查缓存) # 解密凭证 (先查缓存)
SECRETS_ENC="$BOOT_DIR/secrets.enc" SECRETS_ENC="$BOOT_DIR/secrets.enc"
if _kc_load 2>/dev/null; then if _kc_load 2>/dev/null; then
: # 缓存命中 : # 缓存命中
elif [ -f "$SECRETS_ENC" ] && [ -n "$OPENSSL_CMD" ]; then elif [ -f "$SECRETS_ENC" ]; then
echo "" echo ""
for attempt in 1 2 3; do for attempt in 1 2 3; do
read -rs -p " 输入主密码解密凭证 (第 $attempt/3 次): " PASSWORD read -rs -p " 输入主密码解密凭证 (第 $attempt/3 次): " PASSWORD
echo "" echo ""
DECRYPTED=$($OPENSSL_CMD enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in "$SECRETS_ENC" -pass pass:"$PASSWORD" 2>/dev/null) || true DECRYPTED=$(_do_decrypt "$PASSWORD" "$SECRETS_ENC") || true
PASSWORD="" PASSWORD=""
if [ -n "$DECRYPTED" ]; then if [ -n "$DECRYPTED" ]; then
while IFS= read -r line; do while IFS= read -r line; do

View File

@ -261,16 +261,29 @@ $k=$v"
warn "Keychain 缓存失败 (不影响使用)" warn "Keychain 缓存失败 (不影响使用)"
} }
# 解密工具: 优先 node crypto-helper.js (BWENC1 格式), 回退 openssl
CRYPTO_HELPER="$BOOT_DIR/crypto-helper.js"
_decrypt_secrets() {
local pass="$1" enc="$2"
if command -v node &>/dev/null && [ -f "$CRYPTO_HELPER" ]; then
node "$CRYPTO_HELPER" decrypt "$pass" "$enc" 2>/dev/null
elif [ -n "$OPENSSL_CMD" ]; then
$OPENSSL_CMD enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in "$enc" -pass pass:"$pass" 2>/dev/null
else
return 1
fi
}
# 先尝试缓存 # 先尝试缓存
if load_cached_secrets 2>/dev/null; then if load_cached_secrets 2>/dev/null; then
: # 缓存加载成功 : # 缓存加载成功
elif [ -f "$SECRETS_ENC" ] && [ -n "$OPENSSL_CMD" ]; then elif [ -f "$SECRETS_ENC" ]; then
DECRYPTED="" DECRYPTED=""
for attempt in 1 2 3; do for attempt in 1 2 3; do
echo "" echo ""
read -rs -p " 输入主密码解密凭证 (第 $attempt/3 次): " PASSWORD read -rs -p " 输入主密码解密凭证 (第 $attempt/3 次): " PASSWORD
echo "" echo ""
DECRYPTED=$($OPENSSL_CMD enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in "$SECRETS_ENC" -pass pass:"$PASSWORD" 2>/dev/null) || true DECRYPTED=$(_decrypt_secrets "$PASSWORD" "$SECRETS_ENC") || true
PASSWORD="" PASSWORD=""
if [ -n "$DECRYPTED" ]; then if [ -n "$DECRYPTED" ]; then
while IFS= read -r line; do while IFS= read -r line; do

View File

@ -531,7 +531,12 @@ if (Get-CachedSecrets) {
$secretsDecrypted = $true $secretsDecrypted = $true
} }
# 再解密 # 再解密
elseif ((Test-Path $SecretsEnc) -and $opensslCmd) { $cryptoHelper = Join-Path $ScriptDir "crypto-helper.js"
$useNode = (Test-Cmd "node") -and (Test-Path $cryptoHelper)
if (-not $useNode -and -not $opensslCmd) {
Log-Fail "无解密工具 (需要 Node.js 或 OpenSSL)"
}
elseif (Test-Path $SecretsEnc) {
for ($attempt = 1; $attempt -le 3; $attempt++) { for ($attempt = 1; $attempt -le 3; $attempt++) {
$password = Show-PasswordDialog "输入主密码解密凭证`n(非 Gitea 密码, 区分大小写)" $attempt 3 $password = Show-PasswordDialog "输入主密码解密凭证`n(非 Gitea 密码, 区分大小写)" $attempt 3
if (-not $password) { if (-not $password) {
@ -540,10 +545,18 @@ elseif ((Test-Path $SecretsEnc) -and $opensslCmd) {
} }
try { try {
$decrypted = & $opensslCmd enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in $SecretsEnc -pass "pass:$password" 2>$null if ($useNode) {
# Node.js crypto-helper (BWENC1 格式, 跨平台一致)
$decrypted = & node $cryptoHelper decrypt $password $SecretsEnc 2>&1
$decExit = $LASTEXITCODE
} else {
# OpenSSL 回退 (仅支持 Salted__ 格式)
$decrypted = & $opensslCmd enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in $SecretsEnc -pass "pass:$password" 2>$null
$decExit = $LASTEXITCODE
}
$password = $null # 立即清零 $password = $null # 立即清零
if ($decrypted) { if ($decExit -eq 0 -and $decrypted -and $decrypted -notmatch 'WRONG_PASSWORD|WRONG_FORMAT|bad decrypt|bad magic') {
$count = 0 $count = 0
foreach ($line in $decrypted -split "`n") { foreach ($line in $decrypted -split "`n") {
$line = $line.Trim() $line = $line.Trim()