public final class SelfSignedCertificate extends Object
The trust model this class serves, stated so it is not mislaid: self-signed certificates authenticate NOTHING by themselves - anything can mint one. Trust comes from PINNING: each side holds an operator-controlled list of SHA-256 fingerprints and accepts a peer only when the presented certificate's fingerprint is on it. This class produces the identity and the fingerprint; the pin list and its enforcement live in the TLS phases that follow. Nothing here must ever grow an "accept any self-signed" convenience.
One certificate per instance, both roles. A License Manager is a TLS server to Servers and to inbound peers, and a TLS client to outbound peers; a Server is a client only. The certificate therefore carries Extended Key Usage of BOTH serverAuth and clientAuth, so one identity file serves every link the instance participates in.
Key type: EC P-256 with ECDSA/SHA-256 - the mainstream TLS 1.3 signature suite, available in every Java 8 JRE without providers. (Ed25519, the long-term aim of spec 5.10, arrived in Java 15 and can replace P-256 here when the runtime floor allows; the DER skeleton is the same.)
Verification pedigree: the encoder is hand-written (Der); every certificate produced is therefore immediately re-parsed through the JDK's own CertificateFactory and self-verified with X509Certificate.verify() before being returned, so a malformed encoding cannot leave this class as a success.
| Modifier and Type | Field and Description |
|---|---|
static String | ALIASThe alias the identity is stored under inside the PKCS#12 file. |
| Modifier and Type | Method and Description |
|---|---|
static String | fingerprintOf(X509Certificate cert)The SHA-256 fingerprint of any certificate's DER encoding. |
static SelfSignedCertificate | generate(String commonName, String dnsName, int validityDays)Generates a new EC P-256 key pair and a self-signed X.509 v3 certificate for it. |
X509Certificate | getCertificate()Gets the certificate. |
String | getFingerprint()The SHA-256 fingerprint of the certificate's DER encoding - the value a peer pins. |
PrivateKey | getPrivateKey()Gets the private key. |
static SelfSignedCertificate | load(File file, char[] password)Loads an identity previously written by save(File,char[]). |
void | save(File file, char[] password)Saves this identity - private key and certificate - to a PKCS#12 file. |
public static final String ALIAS
public static SelfSignedCertificate generate(String commonName, String dnsName, int validityDays) throws GeneralSecurityException
The certificate is marked CA:false (critical), KeyUsage digitalSignature (critical), EKU serverAuth+clientAuth, and carries the host name as a dNSName SubjectAltName - required by modern TLS stacks, which ignore the CN for host matching.
commonName - The subject CN, e.g. the instance identity "host:port".dnsName - The DNS name for SubjectAltName; when null, commonName is used up to any ':' so a "host:port" identity yields "host".validityDays - How long the certificate is valid from now, e.g. 3650.GeneralSecurityException - If key generation, signing or self-verification fails.public void save(File file, char[] password) throws GeneralSecurityException, IOException
The file holds a private key and must be protected as one: owned by the service account, unreadable by others, excluded from unencrypted backups, never committed. The same handling the hardening document requires for the ACME key directory.
file - The file to write, conventionally with a .p12 extension.password - The store and key password. Callers should wipe the array afterwards.GeneralSecurityException - If the key store cannot be built.IOException - If the file cannot be written.public static SelfSignedCertificate load(File file, char[] password) throws GeneralSecurityException, IOException
save(File,char[]).file - The PKCS#12 file.password - The store and key password.GeneralSecurityException - If the store cannot be opened, the alias is missing, or the entry is not a private key with an X.509 chain.IOException - If the file cannot be read.public X509Certificate getCertificate()
public PrivateKey getPrivateKey()
public String getFingerprint() throws GeneralSecurityException
Uppercase hexadecimal, colon-separated pairs, the form every TLS tool prints, so an operator can compare it against openssl or a browser without transformation.
GeneralSecurityException - If the certificate cannot be re-encoded.public static String fingerprintOf(X509Certificate cert) throws GeneralSecurityException
cert - The certificate.GeneralSecurityException - If the certificate cannot be re-encoded.Phantom® and NetPhantom® are registered trademarks of Mindus SARL.
© 2026 Mindus SARL. All rights reserved.