diff --git a/backend/app/__pycache__/alipay_provider.cpython-313.pyc b/backend/app/__pycache__/alipay_provider.cpython-313.pyc index d8ad69b..8148cca 100644 Binary files a/backend/app/__pycache__/alipay_provider.cpython-313.pyc and b/backend/app/__pycache__/alipay_provider.cpython-313.pyc differ diff --git a/backend/app/alipay_provider.py b/backend/app/alipay_provider.py index f7effa7..0fb924b 100644 --- a/backend/app/alipay_provider.py +++ b/backend/app/alipay_provider.py @@ -76,10 +76,24 @@ def _load_certificate_bundle(path_value: str, label: str): raise AlipayTransferError(f"{label}文件不存在,请检查对应 .env 绝对路径") content = Path(path_value).read_bytes() blocks = re.findall(rb"-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----", content, re.DOTALL) - try: - return [x509.load_pem_x509_certificate(block) for block in blocks] - except Exception as exc: - raise AlipayTransferError(f"{label}格式无效,应为 PEM 编码的 X.509 证书集合") from exc + certificates = [] + parse_errors = [] + for block in blocks: + try: + certificates.append(x509.load_pem_x509_certificate(block)) + except (TypeError, ValueError) as exc: + # Alipay's root bundle contains RSA, SM2 and ECC certificates. + # Some cryptography/OpenSSL builds cannot decode the SM2 + # certificate even though the RSA certificates needed for RSA2 + # are valid. Parse each PEM independently so one unsupported + # non-RSA certificate does not prevent the service from starting. + parse_errors.append(exc) + if not certificates: + cause = parse_errors[0] if parse_errors else None + raise AlipayTransferError( + f"{label}格式无效,应为包含有效 RSA 证书的 PEM X.509 证书集合" + ) from cause + return certificates def _certificate_serial(certificate) -> str: diff --git a/backend/tests/__pycache__/test_alipay_provider.cpython-313-pytest-9.1.1.pyc b/backend/tests/__pycache__/test_alipay_provider.cpython-313-pytest-9.1.1.pyc index 432bf2c..5a93b95 100644 Binary files a/backend/tests/__pycache__/test_alipay_provider.cpython-313-pytest-9.1.1.pyc and b/backend/tests/__pycache__/test_alipay_provider.cpython-313-pytest-9.1.1.pyc differ diff --git a/backend/tests/test_alipay_provider.py b/backend/tests/test_alipay_provider.py index fa3a03e..d8ed369 100644 --- a/backend/tests/test_alipay_provider.py +++ b/backend/tests/test_alipay_provider.py @@ -149,3 +149,23 @@ def test_root_certificate_serial_ignores_non_rsa_certificates(): expected = md5(b"CN=Alipay,O=Example,C=CN41259").hexdigest() assert alipay_provider._root_certificate_serial([sm2, rsa, ecc]) == expected + + +def test_certificate_bundle_keeps_valid_certificates_when_one_block_is_unsupported(monkeypatch, tmp_path): + bundle = tmp_path / "alipayRootCert.crt" + bundle.write_bytes( + b"-----BEGIN CERTIFICATE-----\nBAD\n-----END CERTIFICATE-----\n" + b"-----BEGIN CERTIFICATE-----\nGOOD\n-----END CERTIFICATE-----\n" + ) + valid_certificate = object() + + class FakeX509: + @staticmethod + def load_pem_x509_certificate(block): + if b"BAD" in block: + raise ValueError("unsupported SM2 certificate") + return valid_certificate + + monkeypatch.setitem(__import__("sys").modules, "cryptography.x509", FakeX509) + + assert alipay_provider._load_certificate_bundle(str(bundle), "支付宝根证书") == [valid_certificate]