When working with OAuth providers like Instagram that require HTTPS, developers often need to create self-signed certificates for local development. The specific errors you're seeing indicate two fundamental problems:
- Missing Subject Alternative Name (SAN) extension
- Certificate chain validation failure despite importing to Trusted Root
The original script you referenced creates a basic certificate without SAN. Here's an improved OpenSSL configuration file (ssl.conf) that includes all necessary extensions:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C = US
ST = California
L = San Francisco
O = DevOrg
OU = Dev
CN = localhost
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
Run these commands to generate a properly configured certificate:
# Generate private key
openssl genrsa -out localhost.key 2048
# Create CSR
openssl req -new -key localhost.key -out localhost.csr -config ssl.conf
# Generate certificate with SAN
openssl x509 -req -sha256 -days 365 -in localhost.csr \
-signkey localhost.key -out localhost.crt \
-extfile ssl.conf -extensions v3_req
After generating the certificate:
- Open Chrome and navigate to chrome://settings/certificates
- Go to "Authorities" tab
- Click "Import" and select your localhost.crt file
- Check "Trust this certificate for identifying websites"
For Node.js HTTPS server implementation:
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('localhost.key'),
cert: fs.readFileSync('localhost.crt')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Secure connection established\n');
}).listen(443);
After implementation:
- Restart Chrome completely (chrome://restart)
- Verify certificate details at chrome://net-internals/#hsts
- Check for system-wide certificate stores that might interfere
Remember that modern browsers have strict requirements for certificates, and properly configuring SAN is now mandatory for local development certificates.
html
When setting up HTTPS locally for OAuth testing (e.g., with Instagram's API), Chrome often rejects self-signed certificates even after importing them to Trusted Root Certification Authorities. The two most common errors are:
- ERR_CERT_AUTHORITY_INVALID - Chrome doesn't trust your Certificate Authority (CA)
- Missing Subject Alternative Name (SAN) - Modern browsers require SAN extensions
Here's how to generate a certificate that Chrome will trust:
openssl req -x509 -nodes -newkey rsa:2048 -keyout server.key -out server.crt -days 365 \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1" \
-addext "extendedKeyUsage=serverAuth"
After generation:
- Import
server.crt
to Trusted Root Certification Authorities - Restart Chrome completely (chrome://restart)
- Verify in chrome://settings/certificates
Here's how to use the certificate in a Node.js server:
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('HTTPS working!');
}).listen(443);
If problems continue:
- Clear Chrome's SSL cache: chrome://net-internals/#hsts
- Check certificate chain completeness
- Verify system time is correct
- Try using
mkcert
tool as alternative
For a more reliable solution:
# Install mkcert
brew install mkcert # macOS
mkcert -install
# Create certificate
mkcert localhost 127.0.0.1 ::1