A self-signed certificate contains a public key, identity information, validity dates, and a digital signature created with the corresponding private key. Unlike a certificate issued by a separate certificate authority, it does not establish an independent chain of trust. Verifying its signature demonstrates that the certificate was signed using the associated private key; it does not independently prove that the named organization or server is legitimate.
Developers commonly use self-signed certificates to enable HTTPS on local applications, cloud virtual machines, and temporary test environments. For example, an engineer can configure a development API on a virtual machine with a self-signed certificate and configure a test client to trust that certificate. TLS can then provide encryption, integrity, and server authentication within that explicitly configured trust relationship. Without trusted certificate validation, an encrypted connection can still be vulnerable to impersonation.
OpenSSL can generate a development certificate and its private key in one operation. A typical command is: openssl req -x509 -newkey rsa:2048 -sha256 -days 30 -nodes -keyout dev.key -out dev.crt -subj "/CN=dev.example.test" -addext "subjectAltName=DNS:dev.example.test,DNS:localhost,IP:127.0.0.1". The -x509 option produces a self-signed certificate rather than a certificate signing request. The subject alternative name extension identifies the DNS names and IP addresses clients may use; relying on the common name alone is insufficient for modern hostname validation.
The -nodes option in this example leaves the private key unencrypted, which can simplify unattended development-server startup. Restrict access to dev.key, such as with chmod 600 dev.key on Unix-like systems, and never commit it to source control. The certificate itself is generally public information, whereas possession of the private key enables impersonation of the certificate holder. Use appropriate key protection and secret distribution mechanisms for the deployment environment.
Clients normally reject an unfamiliar self-signed certificate. For a controlled test, curl --cacert dev.crt https://dev.example.test can explicitly trust the supplied certificate while retaining certificate verification, provided DNS resolves the hostname to the test server. Distribute the certificate through a trusted channel or verify its fingerprint independently before trusting it. Disabling verification with options such as curl -k suppresses authentication checks and should not become an application configuration or production workaround.
Self-signed does not mean weak encryption, expired, or automatically unsuitable for every production use. The central trade-off is trust distribution and lifecycle management, not necessarily cryptographic strength. Individually trusted certificates become difficult to rotate across many clients. A private certificate authority can simplify this by issuing many certificates beneath a shared trust anchor. Its root certificate is typically self-signed, but the certificates it issues are CA-signed, not self-signed.
In cloud deployments, certificates can be installed directly on application servers or imported into compatible certificate-management services for supported load balancers. Importing a self-signed certificate does not make browsers trust it, and imported certificates require an explicit renewal and replacement process. Public-facing applications normally use certificates issued by a publicly trusted certificate authority.
SSH key generation is a related development task but uses a different trust model. For example, ssh-keygen -t ed25519 -f ./dev_ssh creates an SSH key pair, not an X.509 TLS certificate. The public key can authorize access to a development server while the private key remains with the developer. SSH host keys and known_hosts establish server trust separately; generating a self-signed HTTPS certificate does not configure SSH access.