MacOS下无法安装Python证书的问题求助
Python MIME邮件服务报错及证书安装权限问题
问题现象
我用Python编写了基于MIME的邮件发送服务,运行时抛出以下错误:
Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 360, in send self.sock.sendall(s) OSError: [Errno 9] Bad file descriptor During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/kiansahafi/PycharmProjects/test/Email/main_email.py", line 10, in <module> DatabaseRepositoryInstance.update_database_task() File "/Users/kiansahafi/PycharmProjects/test/Email/DatabaseRepository.py", line 22, in update_database_task sendEmailInstance.send_email(subject, body, to_email) File "/Users/kiansahafi/PycharmProjects/test/Email/send_email.py", line 63, in send_email server.quit() File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 999, in quit res = self.docmd("quit") File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 426, in docmd self.putcmd(cmd, args) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 373, in putcmd self.send(str) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 363, in send raise SMTPServerDisconnected('Server not connected') smtplib.SMTPServerDisconnected: Server not connected [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)
已尝试的解决方法及新问题
- 执行官方证书安装脚本(加
sudo)仍报错:
❯ /Applications/Python\ 3.11/Install\ Certificates.command ; exit; -- pip install --upgrade certifi Requirement already satisfied: certifi in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (2023.11.17) -- removing any existing file or link -- creating symlink to certifi certificate bundle -- setting permissions Traceback (most recent call last): File "<stdin>", line 44, in <module> File "<stdin>", line 40, in main PermissionError: [Errno 1] Operation not permitted: 'cert.pem' Saving session...completed. [Process completed]
- 给终端和Finder授予全磁盘访问权限,问题未解决。
设备环境
- M1 MacBook Pro
- macOS 14.0
- 编辑器:PyCharm
- 已尝试升级Python和pip,效果未知
可行解决方案
方案1:手动指定certifi证书路径
在邮件发送代码中直接指定certifi提供的证书文件,绕过系统证书限制:
import smtplib import ssl import certifi from email.mime.text import MIMEText def send_email(subject, body, to_email): # 配置邮件内容 msg = MIMEText(body) msg['Subject'] = subject msg['From'] = 'your_email@example.com' msg['To'] = to_email # 创建带指定证书的SSL上下文 context = ssl.create_default_context(cafile=certifi.where()) # 连接SMTP服务器 with smtplib.SMTP_SSL('smtp.example.com', 465, context=context) as server: server.login('your_email@example.com', 'your_password') server.send_message(msg)
方案2:用Homebrew安装Python替代官方版本
macOS官方Python的证书权限问题常和系统完整性保护(SIP)冲突,Homebrew版本会自动处理证书:
- 安装Homebrew(未安装时执行):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- 安装Python:
brew install python
- 验证Python路径,确保使用Homebrew版本:
which python3 # 预期输出:/usr/local/bin/python3 或 /opt/homebrew/bin/python3
- 在PyCharm中配置该Python解释器,重新运行代码。
方案3:临时关闭SSL验证(仅测试环境)
测试场景下可临时关闭证书验证,生产环境绝对禁止:
import smtplib import ssl from email.mime.text import MIMEText def send_email(subject, body, to_email): msg = MIMEText(body) msg['Subject'] = subject msg['From'] = 'your_email@example.com' msg['To'] = to_email # 创建不验证证书的上下文 context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE with smtplib.SMTP_SSL('smtp.example.com', 465, context=context) as server: server.login('your_email@example.com', 'your_password') server.send_message(msg)
方案4:手动创建证书软链接(绕过权限)
- 查找certifi证书路径:
python3 -c "import certifi; print(certifi.where())" # 输出示例:/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/certifi/cacert.pem
- 手动创建软链接(替换为实际路径):
sudo ln -s /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/certifi/cacert.pem /Library/Frameworks/Python.framework/Versions/3.11/etc/openssl/cert.pem
若提示权限不足,需先关闭SIP:重启Mac按住Command+R进入恢复模式,打开终端执行csrutil disable,重启后执行上述命令,完成后建议重新开启SIP:csrutil enable
内容的提问来源于stack exchange,提问作者kiansahafi
相关产品推荐
相关产品推荐

