152 lines
4.4 KiB
Markdown
152 lines
4.4 KiB
Markdown
|
|
# macOS Certificate Issues in Python Downloads - Analysis and Solutions
|
||
|
|
|
||
|
|
## Common Causes of Certificate Problems on macOS:
|
||
|
|
|
||
|
|
### 1. **Outdated Python Certificates**
|
||
|
|
- Python uses the `certifi` package for SSL certificates
|
||
|
|
- These can become outdated, especially with older Python installations
|
||
|
|
- **Solution**: `python3 -m pip install --upgrade certifi`
|
||
|
|
|
||
|
|
### 2. **macOS System Python (/usr/bin/python3) Issues**
|
||
|
|
- Apple's standard Python uses system certificates from the Keychain
|
||
|
|
- System updates can sometimes damage certificates
|
||
|
|
- **Solution**: Export system certificates and set as SSL_CERT_FILE
|
||
|
|
|
||
|
|
### 3. **macOS Keychain Problems**
|
||
|
|
- macOS manages certificates through the Keychain
|
||
|
|
- System updates can sometimes corrupt certificates
|
||
|
|
- **Solution**: Keychain Access → Certificate Assistant → Evaluate
|
||
|
|
|
||
|
|
### 4. **Python.org Certificates Not Installed**
|
||
|
|
- With Python.org installations, certificates are often not installed automatically
|
||
|
|
- **Solution**: Run `/Applications/Python\ 3.x/Install\ Certificates.command`
|
||
|
|
|
||
|
|
### 5. **Corporate/Proxy Environment**
|
||
|
|
- Corporate proxies with their own certificates
|
||
|
|
- **Solution**: Add corporate CA certificates to Python certificate store
|
||
|
|
|
||
|
|
## Standard macOS Python (/usr/bin/python3) Solutions:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Export system certificates
|
||
|
|
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain > /tmp/system_certs.pem
|
||
|
|
|
||
|
|
# 2. Set environment variable
|
||
|
|
export SSL_CERT_FILE=/tmp/system_certs.pem
|
||
|
|
|
||
|
|
# 3. Update Python certifi for system Python
|
||
|
|
/usr/bin/python3 -m pip install --user --upgrade certifi
|
||
|
|
|
||
|
|
# 4. Update the system
|
||
|
|
# System Settings → General → Software Update
|
||
|
|
|
||
|
|
# 5. Test connection
|
||
|
|
curl -v https://dl.espressif.com
|
||
|
|
```
|
||
|
|
|
||
|
|
## Homebrew Python Solutions:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Install Homebrew CA certificates
|
||
|
|
brew install ca-certificates
|
||
|
|
|
||
|
|
# Install OpenSSL
|
||
|
|
brew install openssl
|
||
|
|
|
||
|
|
# Update Python certifi via Homebrew
|
||
|
|
brew reinstall python-certifi
|
||
|
|
|
||
|
|
# Test Homebrew Python
|
||
|
|
/opt/homebrew/bin/python3 -c "import ssl; print(ssl.get_default_verify_paths())"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Python.org Installation Solutions:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Run Install Certificates Command (if available)
|
||
|
|
/Applications/Python\ 3.11/Install\ Certificates.command
|
||
|
|
# or
|
||
|
|
/Applications/Python\ 3.12/Install\ Certificates.command
|
||
|
|
|
||
|
|
# Manually update certifi
|
||
|
|
python3 -m pip install --upgrade certifi
|
||
|
|
```
|
||
|
|
|
||
|
|
## Debugging Commands for macOS:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Display Python SSL information
|
||
|
|
python3 -c "import ssl, certifi; print('SSL:', ssl.OPENSSL_VERSION); print('Certifi:', certifi.where())"
|
||
|
|
|
||
|
|
# Update certificates
|
||
|
|
python3 -m pip install --upgrade certifi
|
||
|
|
|
||
|
|
# Install Python.app certificates (if available)
|
||
|
|
/Applications/Python\ 3.*/Install\ Certificates.command
|
||
|
|
|
||
|
|
# Homebrew CA certificates
|
||
|
|
brew install ca-certificates
|
||
|
|
|
||
|
|
# Test HTTPS connection
|
||
|
|
python3 -c "import urllib.request; urllib.request.urlopen('https://dl.espressif.com')"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Additional Solution Approaches:
|
||
|
|
|
||
|
|
### Set Environment Variables:
|
||
|
|
```bash
|
||
|
|
export SSL_CERT_FILE=$(python3 -m certifi)
|
||
|
|
export REQUESTS_CA_BUNDLE=$(python3 -m certifi)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Bypass Corporate Proxy:
|
||
|
|
```bash
|
||
|
|
export https_proxy=""
|
||
|
|
export HTTPS_PROXY=""
|
||
|
|
```
|
||
|
|
|
||
|
|
### Manually Download Certificates:
|
||
|
|
```bash
|
||
|
|
# Manually add DigiCert Root CA
|
||
|
|
curl -O https://cacerts.digicert.com/DigiCertGlobalRootG2.crt
|
||
|
|
```
|
||
|
|
|
||
|
|
### Reset Certificate Cache:
|
||
|
|
```bash
|
||
|
|
# Clear pip and certificate caches
|
||
|
|
sudo rm -rf /tmp/pip-* && rm -rf ~/.cache/pip
|
||
|
|
```
|
||
|
|
|
||
|
|
## Python Installation Type Detection:
|
||
|
|
|
||
|
|
Different Python installations on macOS require different approaches:
|
||
|
|
|
||
|
|
### System Python (/usr/bin/python3):
|
||
|
|
- Uses macOS system certificates
|
||
|
|
- Requires system certificate export
|
||
|
|
- Best approach: Extract system certificates and set SSL_CERT_FILE
|
||
|
|
|
||
|
|
### Homebrew Python (/opt/homebrew or /usr/local):
|
||
|
|
- Uses Homebrew-managed certificates
|
||
|
|
- Best approach: Update via brew install ca-certificates
|
||
|
|
|
||
|
|
### Python.org Installation (/Applications/Python):
|
||
|
|
- Often missing certificates initially
|
||
|
|
- Best approach: Run Install Certificates.command script
|
||
|
|
|
||
|
|
## Testing Your Solution:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Test 1: Basic SSL connection
|
||
|
|
python3 -c "import ssl; ssl.create_default_context().check_hostname = True"
|
||
|
|
|
||
|
|
# Test 2: Download test
|
||
|
|
python3 -c "import urllib.request; print('Success:', urllib.request.urlopen('https://dl.espressif.com').status)"
|
||
|
|
|
||
|
|
# Test 3: Certificate path verification
|
||
|
|
python3 -c "import certifi; print('Certifi path:', certifi.where())"
|
||
|
|
|
||
|
|
# Test 4: System certificate access
|
||
|
|
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain | head -20
|
||
|
|
```
|