|
| 1 | +# macOS Certificate Issues in Python Downloads - Analysis and Solutions |
| 2 | + |
| 3 | +## Common Causes of Certificate Problems on macOS: |
| 4 | + |
| 5 | +### 1. **Outdated Python Certificates** |
| 6 | +- Python uses the `certifi` package for SSL certificates |
| 7 | +- These can become outdated, especially with older Python installations |
| 8 | +- **Solution**: `python3 -m pip install --upgrade certifi` |
| 9 | + |
| 10 | +### 2. **macOS System Python (/usr/bin/python3) Issues** |
| 11 | +- Apple's standard Python uses system certificates from the Keychain |
| 12 | +- System updates can sometimes damage certificates |
| 13 | +- **Solution**: Export system certificates and set as SSL_CERT_FILE |
| 14 | + |
| 15 | +### 3. **macOS Keychain Problems** |
| 16 | +- macOS manages certificates through the Keychain |
| 17 | +- System updates can sometimes corrupt certificates |
| 18 | +- **Solution**: Keychain Access → Certificate Assistant → Evaluate |
| 19 | + |
| 20 | +### 4. **Python.org Certificates Not Installed** |
| 21 | +- With Python.org installations, certificates are often not installed automatically |
| 22 | +- **Solution**: Run `/Applications/Python\ 3.x/Install\ Certificates.command` |
| 23 | + |
| 24 | +### 5. **Corporate/Proxy Environment** |
| 25 | +- Corporate proxies with their own certificates |
| 26 | +- **Solution**: Add corporate CA certificates to Python certificate store |
| 27 | + |
| 28 | +## Standard macOS Python (/usr/bin/python3) Solutions: |
| 29 | + |
| 30 | +```bash |
| 31 | +# 1. Export system certificates |
| 32 | +security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain > /tmp/system_certs.pem |
| 33 | + |
| 34 | +# 2. Set environment variable |
| 35 | +export SSL_CERT_FILE=/tmp/system_certs.pem |
| 36 | + |
| 37 | +# 3. Update Python certifi for system Python |
| 38 | +/usr/bin/python3 -m pip install --user --upgrade certifi |
| 39 | + |
| 40 | +# 4. Update the system |
| 41 | +# System Settings → General → Software Update |
| 42 | + |
| 43 | +# 5. Test connection |
| 44 | +curl -v https://dl.espressif.com |
| 45 | +``` |
| 46 | + |
| 47 | +## Homebrew Python Solutions: |
| 48 | + |
| 49 | +```bash |
| 50 | +# Install Homebrew CA certificates |
| 51 | +brew install ca-certificates |
| 52 | + |
| 53 | +# Install OpenSSL |
| 54 | +brew install openssl |
| 55 | + |
| 56 | +# Update Python certifi via Homebrew |
| 57 | +brew reinstall python-certifi |
| 58 | + |
| 59 | +# Test Homebrew Python |
| 60 | +/opt/homebrew/bin/python3 -c "import ssl; print(ssl.get_default_verify_paths())" |
| 61 | +``` |
| 62 | + |
| 63 | +## Python.org Installation Solutions: |
| 64 | + |
| 65 | +```bash |
| 66 | +# Run Install Certificates Command (if available) |
| 67 | +/Applications/Python\ 3.11/Install\ Certificates.command |
| 68 | +# or |
| 69 | +/Applications/Python\ 3.12/Install\ Certificates.command |
| 70 | + |
| 71 | +# Manually update certifi |
| 72 | +python3 -m pip install --upgrade certifi |
| 73 | +``` |
| 74 | + |
| 75 | +## Debugging Commands for macOS: |
| 76 | + |
| 77 | +```bash |
| 78 | +# Display Python SSL information |
| 79 | +python3 -c "import ssl, certifi; print('SSL:', ssl.OPENSSL_VERSION); print('Certifi:', certifi.where())" |
| 80 | + |
| 81 | +# Update certificates |
| 82 | +python3 -m pip install --upgrade certifi |
| 83 | + |
| 84 | +# Install Python.app certificates (if available) |
| 85 | +/Applications/Python\ 3.*/Install\ Certificates.command |
| 86 | + |
| 87 | +# Homebrew CA certificates |
| 88 | +brew install ca-certificates |
| 89 | + |
| 90 | +# Test HTTPS connection |
| 91 | +python3 -c "import urllib.request; urllib.request.urlopen('https://dl.espressif.com')" |
| 92 | +``` |
| 93 | + |
| 94 | +## Additional Solution Approaches: |
| 95 | + |
| 96 | +### Set Environment Variables: |
| 97 | +```bash |
| 98 | +export SSL_CERT_FILE=$(python3 -m certifi) |
| 99 | +export REQUESTS_CA_BUNDLE=$(python3 -m certifi) |
| 100 | +``` |
| 101 | + |
| 102 | +### Bypass Corporate Proxy: |
| 103 | +```bash |
| 104 | +export https_proxy="" |
| 105 | +export HTTPS_PROXY="" |
| 106 | +``` |
| 107 | + |
| 108 | +### Manually Download Certificates: |
| 109 | +```bash |
| 110 | +# Manually add DigiCert Root CA |
| 111 | +curl -O https://cacerts.digicert.com/DigiCertGlobalRootG2.crt |
| 112 | +``` |
| 113 | + |
| 114 | +### Reset Certificate Cache: |
| 115 | +```bash |
| 116 | +# Clear pip and certificate caches |
| 117 | +sudo rm -rf /tmp/pip-* && rm -rf ~/.cache/pip |
| 118 | +``` |
| 119 | + |
| 120 | +## Python Installation Type Detection: |
| 121 | + |
| 122 | +Different Python installations on macOS require different approaches: |
| 123 | + |
| 124 | +### System Python (/usr/bin/python3): |
| 125 | +- Uses macOS system certificates |
| 126 | +- Requires system certificate export |
| 127 | +- Best approach: Extract system certificates and set SSL_CERT_FILE |
| 128 | + |
| 129 | +### Homebrew Python (/opt/homebrew or /usr/local): |
| 130 | +- Uses Homebrew-managed certificates |
| 131 | +- Best approach: Update via brew install ca-certificates |
| 132 | + |
| 133 | +### Python.org Installation (/Applications/Python): |
| 134 | +- Often missing certificates initially |
| 135 | +- Best approach: Run Install Certificates.command script |
| 136 | + |
| 137 | +## Testing Your Solution: |
| 138 | + |
| 139 | +```bash |
| 140 | +# Test 1: Basic SSL connection |
| 141 | +python3 -c "import ssl; ssl.create_default_context().check_hostname = True" |
| 142 | + |
| 143 | +# Test 2: Download test |
| 144 | +python3 -c "import urllib.request; print('Success:', urllib.request.urlopen('https://dl.espressif.com').status)" |
| 145 | + |
| 146 | +# Test 3: Certificate path verification |
| 147 | +python3 -c "import certifi; print('Certifi path:', certifi.where())" |
| 148 | + |
| 149 | +# Test 4: System certificate access |
| 150 | +security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain | head -20 |
| 151 | +``` |
0 commit comments