fix: 证书扫描含pub_key.pem;诊断明确缺少apiclient_cert.pem
服务器仅有私钥无商户证书时V3签名必失败,诊断输出操作指引。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -50,20 +50,41 @@ class Command(BaseCommand):
|
||||
try:
|
||||
private_key = _load_pem_private_key(key_path)
|
||||
self.stdout.write('private_key : 加载成功')
|
||||
cert_path = key_path.replace('apiclient_key.pem', 'apiclient_cert.pem')
|
||||
if os.path.isfile(cert_path):
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
with open(cert_path, 'rb') as f:
|
||||
cert = x509.load_pem_x509_certificate(f.read(), default_backend())
|
||||
matched = _public_keys_match(private_key, cert.public_key())
|
||||
self.stdout.write(
|
||||
f"apiclient_cert.pem 与私钥匹配: {matched} "
|
||||
f"serial={format(cert.serial_number, 'X').upper()}"
|
||||
)
|
||||
else:
|
||||
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
tested = []
|
||||
for fname in sorted(os.listdir(cert_dir)):
|
||||
if not fname.lower().endswith('.pem'):
|
||||
continue
|
||||
if fname.lower() in ('apiclient_key.pem',):
|
||||
continue
|
||||
cert_path = os.path.join(cert_dir, fname)
|
||||
tested.append(fname)
|
||||
try:
|
||||
with open(cert_path, 'rb') as f:
|
||||
data = f.read()
|
||||
if b'PRIVATE KEY' in data:
|
||||
self.stdout.write(f' {fname}: 是私钥,跳过')
|
||||
continue
|
||||
cert = x509.load_pem_x509_certificate(data, default_backend())
|
||||
serial = format(cert.serial_number, 'X').upper()
|
||||
matched = _public_keys_match(private_key, cert.public_key())
|
||||
self.stdout.write(
|
||||
f' {fname}: X509证书 serial={serial} 与私钥匹配={matched}'
|
||||
)
|
||||
except Exception as exc:
|
||||
self.stdout.write(f' {fname}: 非X509商户证书 ({exc})')
|
||||
|
||||
if 'apiclient_cert.pem' not in tested:
|
||||
self.stdout.write(self.style.ERROR(
|
||||
f'缺少 apiclient_cert.pem(与 apiclient_key.pem 同目录): {cert_path}'
|
||||
'\n缺少 apiclient_cert.pem!'
|
||||
'\n请到微信商户平台(1747846572) → 账户中心 → API安全 → 申请API证书'
|
||||
'\n下载证书包,将 apiclient_cert.pem 放到目录:'
|
||||
f'\n {cert_dir}'
|
||||
'\n当前目录只有 apiclient_key.pem,没有商户证书,所以签名必然失败。'
|
||||
'\npub_key.pem 是微信支付平台公钥,不能代替 apiclient_cert.pem。'
|
||||
))
|
||||
except Exception as exc:
|
||||
self.stdout.write(self.style.ERROR(f'私钥/证书检查失败: {exc}'))
|
||||
|
||||
@@ -87,7 +87,9 @@ def resolve_merchant_cert_serial(private_key_path, configured_serial=''):
|
||||
for fname in sorted(os.listdir(cert_dir)):
|
||||
if not fname.lower().endswith('.pem'):
|
||||
continue
|
||||
if 'key' in fname.lower():
|
||||
lower = fname.lower()
|
||||
# 只跳过私钥文件;pub_key.pem 等仍尝试(有人误命名证书)
|
||||
if lower in ('apiclient_key.pem',) or 'private' in lower:
|
||||
continue
|
||||
candidates.append(os.path.join(cert_dir, fname))
|
||||
except OSError as exc:
|
||||
|
||||
Reference in New Issue
Block a user