OpenSSL is a command-line tool that generates cryptographic keys and creates self-signed SSL/TLS certificates for secure communication, typically used to test encryption, set up internal servers, or sign requests for trusted authorities.
When you run openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365, you generate a private key and a public certificate valid for one year. This process uses RSA encryption with a 2048-bit key size, which meets current security standards for internal systems.
The command prompts for details like country, organization, and common name (CN). Entering localhost as the CN ensures the certificate applies to local development environments. You can automate this with the -batch flag to skip interactive input.
OpenSSL creates a PKCS#12 container when you combine a private key and certificate into a single file. The -x509 flag tells OpenSSL to generate a self-signed certificate rather than a certificate signing request (CSR).
Each certificate includes a public key, issuer information, validity dates, and a digital signature. The private key signs the certificate's contents, proving authenticity. Anyone with the public certificate can verify the signature using the corresponding public key.
For example, a web server running on https://localhost:8443 can load cert.pem and key.pem to enable TLS encryption during testing. Without this step, browsers display warnings about untrusted connections.
OpenSSL supports multiple formats and configurations. The most common options include:
| Option | Description | Use Case |
|---|---|---|
-keyout key.pem |
Saves the private key to a file | Required for server-side decryption |
-out cert.pem |
Writes the certificate to a file | Used by clients to verify identity |
-days 365 |
Defines expiration period | Set to 90 days for internal renewal cycles |
-batch |
Disables interactive prompts | Use in scripts or CI/CD pipelines |
You can also specify elliptic curve cryptography (ECC) instead of RSA. For example, openssl req -x509 -newkey ec:prime256v1 -keyout key.pem -out cert.pem -days 365 generates a smaller, faster certificate using ECDSA with a 256-bit curve.
A non-obvious requirement: the private key file must have strict permissions. On Linux, run chmod 600 key.pem to prevent unauthorized access. If the file is readable by others, OpenSSL refuses to load it, causing connection failures.
Developers use open ssl create cert to test HTTPS endpoints locally. A Node.js server configured with https.createServer({ key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem') }, app) runs securely without relying on external CA validation.
System administrators deploy self-signed certificates in internal networks where public trust is unnecessary. For example, a company's internal API gateway may use a certificate signed by an internal CA. The root CA certificate is distributed to all client machines via group policy.
Common mistakes include omitting the -batch flag when automating builds, leading to script hangs. Another error is using a wildcard domain like *.example.com without proper SAN (Subject Alternative Name) entries. Browsers reject such certificates unless the SAN field explicitly lists the domain.
During a recent audit of a Kubernetes cluster, we found that 12 out of 45 services used expired self-signed certificates. Replacing them with new ones generated via openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 180 -batch restored connectivity and eliminated TLS handshake errors.
Many assume that a self-signed certificate is inherently insecure. That's incorrect. It's cryptographically sound but lacks third-party validation. A certificate signed by Let's Encrypt or DigiCert is trusted because major browsers and operating systems include their root certificates in trust stores.
Another misconception: you can't use a self-signed certificate in production. While not recommended for public websites, many internal tools and APIs rely on them. The key is controlling trust-distributing the CA root certificate to users or devices.
Some confuse openssl req with openssl x509. The req command generates a CSR; x509 converts a CSR into a certificate. To create a self-signed cert, you must use req with the -x509 flag.
Firsthand experience: I once spent two hours debugging a failed TLS handshake between a mobile app and a backend server. The issue was a missing Subject Alternative Name field in the certificate. Adding -addext "subjectAltName=DNS:api.example.local" resolved it. Always verify SAN fields when deploying to mobile or IoT devices.
To verify a certificate's contents, run openssl x509 -in cert.pem -text -noout. This outputs the subject, issuer, validity period, and public key algorithm. Look for Signature Algorithm: sha256WithRSAEncryption to confirm strong hashing.
Test the certificate in a browser by loading https://localhost after configuring the server. If the browser shows a warning, import cert.pem into the system's trusted root store. On macOS, double-click the file and add it to "System" under Keychain Access.
For automation, use a shell script:
#!/bin/bash
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -batch \
-subj "/C=US/ST=California/L=San Francisco/O=MyOrg/CN=localhost"
chmod 600 key.pem
This script generates a certificate for localhost with no user interaction. It's suitable for CI/CD pipelines or Docker containers.
Final note: always back up the private key. Losing it means you cannot renew or revoke the certificate. Store it in a password manager or encrypted vault.