基于Hypercorn+FastAPI的客户端证书认证问题排查与实现咨询
问题描述
我需要为客户端生成证书以实现API授权,使用场景如下:
- 用Python的Hypercorn和FastAPI部署API
- 多个Python(httpx)客户端向该API请求数据
- 客户端与服务器间采用证书认证,我会为客户端提供用于身份授权的证书
参考教程生成证书后,客户端请求时出现错误。
服务器代码
async def main(): config = Config.from_mapping(dict( worker_class='trio', certfile='server.cer', keyfile='server.key', verify_mode=VerifyMode.CERT_REQUIRED, bind=f"0.0.0.0:{8000}")) async with trio.open_nursery() as nursery: nursery.start_soon(serve, app, config)
客户端代码
import httpx res = httpx.get("https://localhost:8000/", verify=True, cert=("client.cer", "client.key")) res
错误信息
ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1123)
问题原因与解决步骤
核心问题
错误源于双向SSL认证链路未完全打通:客户端默认不信任自签名的服务器证书,同时服务器未配置验证客户端证书所需的CA根证书。
解决步骤
1. 补全服务器的CA信任配置
Hypercorn仅指定服务器证书和密钥时,无法验证客户端证书的合法性,需添加ca_certs参数指向CA根证书:
async def main(): config = Config.from_mapping(dict( worker_class='trio', certfile='server.cer', keyfile='server.key', # 添加CA根证书,用于验证客户端证书 ca_certs='ca.crt', verify_mode=VerifyMode.CERT_REQUIRED, bind=f"0.0.0.0:{8000}")) async with trio.open_nursery() as nursery: nursery.start_soon(serve, app, config)
ca.crt是生成客户端证书时使用的CA根证书,需确保服务器进程能读取该文件。
2. 客户端指定信任的CA证书
客户端verify=True会使用系统默认CA池验证服务器证书,而自签名服务器证书不在默认池内,需显式指定信任的CA根证书(或服务器证书本身):
import httpx # 用CA根证书验证服务器证书,同时提供客户端证书 res = httpx.get( "https://localhost:8000/", verify="ca.crt", # 指定信任的CA根证书 cert=("client.cer", "client.key") ) print(res.status_code)
若服务器证书是CA签名的,用CA根证书即可;若为自签名服务器证书,直接传入server.cer给verify参数也可。
3. 证书生成环节关键注意事项
- 服务器证书、客户端证书必须由同一个CA根证书签名,不能各自独立自签名
- 确保所有证书文件权限正确,服务器和客户端进程可读取文件内容
内容的提问来源于stack exchange,提问作者Phil997
相关产品推荐
相关产品推荐

