Secure bootstrapping is the process of establishing trust in a system from a minimal trusted base. This guide covers comprehensive implementation of secure bootstrapping mechanisms for Java applications, including TPM integration, hardware-based attestation, and secure secret distribution.
Table of Contents
- Dependencies and Setup
- Hardware Security Integration
- Root of Trust Establishment
- Secure Configuration Management
- Cryptographic Key Management
- Trust Chain Validation
- Zero-Trust Network Bootstrap
- Secure Service Discovery
- Monitoring and Auditing
- Testing and Validation
1. Dependencies and Setup
Maven Dependencies
<properties>
<bouncycastle.version>1.76</bouncycastle.version>
<tss2j.version>2.3.1</tss2j.version>
<eddsa.version>0.3.0</eddsa.version>
<jna.version>5.13.0</jna.version>
<jackson.version>2.15.3</jackson.version>
<jwt.version>4.4.0</jwt.version>
<grpc.version>1.59.0</grpc.version>
<log4j.version>2.20.0</log4j.version>
</properties>
<dependencies>
<!-- Cryptography -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<!-- TPM 2.0 Support -->
<dependency>
<groupId>com.github.tpm2-software</groupId>
<artifactId>tss2j</artifactId>
<version>${tss2j.version}</version>
</dependency>
<!-- EdDSA for modern crypto -->
<dependency>
<groupId>net.i2p.crypto</groupId>
<artifactId>eddsa</artifactId>
<version>${eddsa.version}</version>
</dependency>
<!-- Hardware Access -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna.version}</version>
</dependency>
<!-- Secure Communication -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<!-- JSON and JWT -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!-- Secure Logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
Project Structure
secure-bootstrap/ ├── src/main/java/com/secure/bootstrap/ │ ├── hardware/ │ │ ├── tpm/ │ │ ├── hsm/ │ │ └── secureelement/ │ ├── crypto/ │ │ ├── keys/ │ │ ├── signatures/ │ │ └── encryption/ │ ├── attestation/ │ │ ├── local/ │ │ ├── remote/ │ │ └── verification/ │ ├── configuration/ │ │ ├── secureloader/ │ │ ├── secrets/ │ │ └── validation/ │ ├── network/ │ │ ├── discovery/ │ │ ├── authentication/ │ │ └── authorization/ │ ├── trust/ │ │ ├── chain/ │ │ ├── anchor/ │ │ └── policy/ │ └── monitoring/ │ ├── audit/ │ ├── metrics/ │ └── health/ └── src/main/resources/ ├── security/ ├── policies/ └── certificates/
2. Hardware Security Integration
TPM 2.0 Integration Service
package com.secure.bootstrap.hardware.tpm;
import tss.*;
import tss.tpm.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.*;
@Service
public class TpmService {
private static final Logger logger = LoggerFactory.getLogger(TpmService.class);
private Tpm tpm;
private TpmDevice device;
private boolean initialized = false;
// TPM persistent handles
private static final long PRIMARY_KEY_HANDLE = 0x81000000L;
private static final long ENDORSEMENT_KEY_HANDLE = 0x81000001L;
private static final long ATTESTATION_KEY_HANDLE = 0x81000002L;
public synchronized void initialize() throws TpmException {
if (initialized) return;
try {
// Connect to TPM device
device = TpmDeviceLocal.getTpmDevice();
device.connect();
// Create TPM instance
tpm = new Tpm();
tpm._setDevice(device);
// Start up TPM
tpm.Startup(TPM_SU.CLEAR);
// Perform self-test
performSelfTest();
// Create primary keys
createPrimaryKeys();
initialized = true;
logger.info("TPM initialized successfully");
} catch (Exception e) {
logger.error("Failed to initialize TPM", e);
throw new TpmException("TPM initialization failed", e);
}
}
private void performSelfTest() throws TpmException {
try {
// Get TPM capabilities
TPM_CAP capability = TPM_CAP.from(TPM_CAP.TPM_PROPERTIES);
TPMU_CAPABILITIES caps = tpm.GetCapability(
capability,
TPM_PT.TOTAL_COMMANDS.toInt(),
1
);
// Verify TPM properties
TPMS_CAPABILITY_DATA capData = (TPMS_CAPABILITY_DATA)caps;
if (capData.data.getLength() == 0) {
throw new TpmException("TPM capability check failed");
}
logger.debug("TPM self-test passed");
} catch (Exception e) {
throw new TpmException("TPM self-test failed", e);
}
}
private void createPrimaryKeys() throws TpmException {
try {
// Create storage primary key
TPMS_SENSITIVE_CREATE sensCreate = new TPMS_SENSITIVE_CREATE(
new byte[0], // No auth value
new byte[0] // Empty sensitive data
);
TPMS_PCR_SELECTION[] pcrSelection = new TPMS_PCR_SELECTION[0];
TPMA_OBJECT objectAttributes = new TPMA_OBJECT(
TPMA_OBJECT.fixedTPM |
TPMA_OBJECT.fixedParent |
TPMA_OBJECT.sensitiveDataOrigin |
TPMA_OBJECT.userWithAuth |
TPMA_OBJECT.noDA |
TPMA_OBJECT.restricted |
TPMA_OBJECT.decrypt
);
TPMT_PUBLIC publicTemplate = new TPMT_PUBLIC(
TPM_ALG_ID.SHA256,
objectAttributes,
new byte[0],
new TPMS_RSA_PARMS(
new TPMT_SYM_DEF_OBJECT(TPM_ALG_ID.NULL, 0, TPM_ALG_ID.NULL),
new TPMS_SCHEME_OAEP(TPM_ALG_ID.SHA256),
2048,
65537
),
new TPM2B_PUBLIC_KEY_RSA(new byte[256])
);
CreatePrimaryResponse storagePrimary = tpm.CreatePrimary(
new TPM_HANDLE(TPM_RH.OWNER),
sensCreate,
publicTemplate,
new byte[0],
pcrSelection
);
// Persist the key
tpm.EvictControl(
new TPM_HANDLE(TPM_RH.OWNER),
storagePrimary.handle,
PRIMARY_KEY_HANDLE
);
logger.info("Primary storage key created and persisted");
} catch (Exception e) {
throw new TpmException("Failed to create primary keys", e);
}
}
public byte[] generateSealedSecret(String secretName, byte[] secretData)
throws TpmException {
try {
if (!initialized) initialize();
// Create sealing policy based on PCR values
TPMS_PCR_SELECTION[] pcrSelection = new TPMS_PCR_SELECTION[1];
pcrSelection[0] = new TPMS_PCR_SELECTION(
TPM_ALG_ID.SHA256,
new TPMS_PCR_SELECTION[] { new TPMS_PCR_SELECTION(0) }
);
// Read current PCR values
PCR_ReadResponse pcrValues = tpm.PCR_Read(pcrSelection);
// Create sealed secret
CreateResponse sealed = tpm.Create(
new TPM_HANDLE(PRIMARY_KEY_HANDLE),
new TPMS_SENSITIVE_CREATE(new byte[0], secretData),
new TPMT_PUBLIC(
TPM_ALG_ID.SHA256,
new TPMA_OBJECT(
TPMA_OBJECT.fixedTPM |
TPMA_OBJECT.fixedParent |
TPMA_OBJECT.noDA
),
pcrValues.pcrValues.buffer,
new TPMS_KEYEDHASH_PARMS(
new TPMT_KEYEDHASH_SCHEME(TPM_ALG_ID.HMAC, TPM_ALG_ID.SHA256)
),
new TPM2B_DIGEST_KEYEDHASH(new byte[32])
),
new byte[0],
pcrSelection
);
// Store sealed secret metadata
SealedSecretMetadata metadata = new SealedSecretMetadata(
secretName,
sealed.outPrivate.toBytes(),
sealed.outPublic.toBytes(),
pcrValues.pcrValues.toBytes(),
System.currentTimeMillis()
);
logger.info("Secret '{}' sealed with TPM", secretName);
return sealed.outPrivate.toBytes();
} catch (Exception e) {
throw new TpmException("Failed to seal secret", e);
}
}
public byte[] unsealSecret(byte[] sealedData) throws TpmException {
try {
if (!initialized) initialize();
// Load sealed data
LoadResponse loaded = tpm.Load(
new TPM_HANDLE(PRIMARY_KEY_HANDLE),
new TPM2B_PRIVATE(sealedData),
new TPM2B_PUBLIC(new byte[0])
);
// Unseal (requires PCR state to match)
byte[] unsealed = tpm.Unseal(loaded.handle);
logger.debug("Secret successfully unsealed");
return unsealed;
} catch (Exception e) {
throw new TpmException("Failed to unseal secret", e);
}
}
public AttestationData generatePlatformAttestation() throws TpmException {
try {
if (!initialized) initialize();
// Read PCR values for attestation
TPMS_PCR_SELECTION[] pcrSelection = new TPMS_PCR_SELECTION[1];
pcrSelection[0] = new TPMS_PCR_SELECTION(
TPM_ALG_ID.SHA256,
new TPMS_PCR_SELECTION[] {
new TPMS_PCR_SELECTION(0), // BIOS
new TPMS_PCR_SELECTION(1), // Platform config
new TPMS_PCR_SELECTION(2), // Option ROM
new TPMS_PCR_SELECTION(3), // Option ROM config
new TPMS_PCR_SELECTION(4), // Bootloader
new TPMS_PCR_SELECTION(5), // Boot config
new TPMS_PCR_SELECTION(7) // Secure boot
}
);
PCR_ReadResponse pcrValues = tpm.PCR_Read(pcrSelection);
// Create attestation key if not exists
if (!keyExists(ATTESTATION_KEY_HANDLE)) {
createAttestationKey();
}
// Generate quote (signed PCR values)
TPML_PCR_SELECTION pcrSelect = new TPML_PCR_SELECTION(pcrSelection);
byte[] qualifyingData = new SecureRandom().generateSeed(32);
QuoteResponse quote = tpm.Quote(
new TPM_HANDLE(ATTESTATION_KEY_HANDLE),
qualifyingData,
new TPMT_SIG_SCHEME(TPM_ALG_ID.ECDSA, TPM_ALG_ID.SHA256),
pcrSelect
);
// Get attestation key certificate
byte[] akCert = getAttestationKeyCertificate();
// Build attestation data
AttestationData attestation = new AttestationData();
attestation.setPcrValues(pcrValues.pcrValues.toBytes());
attestation.setQuote(quote.quoted.toBytes());
attestation.setSignature(quote.signature.toBytes());
attestation.setAkCertificate(akCert);
attestation.setTimestamp(System.currentTimeMillis());
logger.info("Platform attestation generated");
return attestation;
} catch (Exception e) {
throw new TpmException("Failed to generate platform attestation", e);
}
}
private boolean keyExists(long handle) throws TpmException {
try {
tpm.ReadPublic(new TPM_HANDLE(handle));
return true;
} catch (Exception e) {
return false;
}
}
private void createAttestationKey() throws TpmException {
try {
TPMS_SENSITIVE_CREATE sensCreate = new TPMS_SENSITIVE_CREATE(
new byte[0],
new byte[0]
);
TPMA_OBJECT objectAttributes = new TPMA_OBJECT(
TPMA_OBJECT.fixedTPM |
TPMA_OBJECT.fixedParent |
TPMA_OBJECT.sensitiveDataOrigin |
TPMA_OBJECT.userWithAuth |
TPMA_OBJECT.sign
);
TPMT_PUBLIC publicTemplate = new TPMT_PUBLIC(
TPM_ALG_ID.SHA256,
objectAttributes,
new byte[0],
new TPMS_ECC_PARMS(
new TPMT_SYM_DEF_OBJECT(TPM_ALG_ID.NULL, 0, TPM_ALG_ID.NULL),
new TPMS_SIG_SCHEME_ECDSA(TPM_ALG_ID.SHA256),
TPM_ECC_CURVE.NIST_P256,
new TPMS_NULL_KDF_SCHEME()
),
new TPMS_ECC_POINT(new byte[32], new byte[32])
);
CreateResponse ak = tpm.Create(
new TPM_HANDLE(PRIMARY_KEY_HANDLE),
sensCreate,
publicTemplate,
new byte[0],
new TPMS_PCR_SELECTION[0]
);
LoadResponse loaded = tpm.Load(
new TPM_HANDLE(PRIMARY_KEY_HANDLE),
ak.outPrivate,
ak.outPublic
);
tpm.EvictControl(
new TPM_HANDLE(TPM_RH.OWNER),
loaded.handle,
ATTESTATION_KEY_HANDLE
);
logger.debug("Attestation key created and persisted");
} catch (Exception e) {
throw new TpmException("Failed to create attestation key", e);
}
}
private byte[] getAttestationKeyCertificate() {
// In production, this would retrieve the actual EK certificate
// For now, generate a placeholder
return "TPM_ATTESTATION_KEY_CERTIFICATE_PLACEHOLDER".getBytes();
}
public void shutdown() {
if (device != null && device.isConnected()) {
try {
tpm.Shutdown(TPM_SU.CLEAR);
device.close();
initialized = false;
logger.info("TPM shutdown completed");
} catch (Exception e) {
logger.error("Error during TPM shutdown", e);
}
}
}
}
// Supporting classes
class TpmException extends Exception {
public TpmException(String message) {
super(message);
}
public TpmException(String message, Throwable cause) {
super(message, cause);
}
}
class SealedSecretMetadata {
private final String name;
private final byte[] sealedData;
private final byte[] publicData;
private final byte[] pcrValues;
private final long creationTime;
public SealedSecretMetadata(String name, byte[] sealedData, byte[] publicData,
byte[] pcrValues, long creationTime) {
this.name = name;
this.sealedData = sealedData;
this.publicData = publicData;
this.pcrValues = pcrValues;
this.creationTime = creationTime;
}
// Getters
public String getName() { return name; }
public byte[] getSealedData() { return sealedData; }
public byte[] getPublicData() { return publicData; }
public byte[] getPcrValues() { return pcrValues; }
public long getCreationTime() { return creationTime; }
}
class AttestationData {
private byte[] pcrValues;
private byte[] quote;
private byte[] signature;
private byte[] akCertificate;
private long timestamp;
// Getters and setters
public byte[] getPcrValues() { return pcrValues; }
public void setPcrValues(byte[] pcrValues) { this.pcrValues = pcrValues; }
public byte[] getQuote() { return quote; }
public void setQuote(byte[] quote) { this.quote = quote; }
public byte[] getSignature() { return signature; }
public void setSignature(byte[] signature) { this.signature = signature; }
public byte[] getAkCertificate() { return akCertificate; }
public void setAkCertificate(byte[] akCertificate) { this.akCertificate = akCertificate; }
public long getTimestamp() { return timestamp; }
public void setTimestamp(long timestamp) { this.timestamp = timestamp; }
}
Hardware Security Module (HSM) Integration
package com.secure.bootstrap.hardware.hsm;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.cert.*;
import java.security.spec.*;
import java.util.*;
public class HsmService {
private final KeyStore hsmKeyStore;
private final Provider hsmProvider;
private final SecureRandom secureRandom;
public HsmService(String providerClass, String config)
throws GeneralSecurityException {
// Initialize HSM provider
this.hsmProvider = Security.getProvider(providerClass);
if (hsmProvider == null) {
throw new IllegalStateException("HSM provider not available: " + providerClass);
}
// Initialize key store
this.hsmKeyStore = KeyStore.getInstance("PKCS11", hsmProvider);
// Load with PIN (should come from secure source)
char[] pin = getHsmPin();
hsmKeyStore.load(null, pin);
// Secure random
this.secureRandom = SecureRandom.getInstanceStrong();
Arrays.fill(pin, ' ');
}
public String generateRootKey(String keyAlias, String keyLabel)
throws GeneralSecurityException {
// Generate RSA key pair in HSM
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", hsmProvider);
keyGen.initialize(4096, secureRandom);
KeyPair keyPair = keyGen.generateKeyPair();
// Store in HSM key store
KeyStore.ProtectionParameter protection =
new KeyStore.PasswordProtection("".toCharArray());
KeyStore.PrivateKeyEntry privateKeyEntry =
new KeyStore.PrivateKeyEntry(keyPair.getPrivate(), null);
hsmKeyStore.setEntry(keyAlias, privateKeyEntry, protection);
// Generate self-signed certificate
X509Certificate cert = generateSelfSignedCertificate(keyPair, keyLabel);
// Store certificate
hsmKeyStore.setCertificateEntry(keyAlias + "-cert", cert);
return Base64.getEncoder().encodeToString(cert.getEncoded());
}
public byte[] signWithHsm(String keyAlias, byte[] data)
throws GeneralSecurityException {
PrivateKey privateKey = (PrivateKey) hsmKeyStore.getKey(keyAlias, "".toCharArray());
Signature signature = Signature.getInstance("SHA256withRSA", hsmProvider);
signature.initSign(privateKey, secureRandom);
signature.update(data);
return signature.sign();
}
public boolean verifyWithHsm(String keyAlias, byte[] data, byte[] signatureBytes)
throws GeneralSecurityException {
Certificate cert = hsmKeyStore.getCertificate(keyAlias + "-cert");
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(cert.getPublicKey());
signature.update(data);
return signature.verify(signatureBytes);
}
public byte[] encryptWithHsm(String keyAlias, byte[] data)
throws GeneralSecurityException {
Certificate cert = hsmKeyStore.getCertificate(keyAlias + "-cert");
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", hsmProvider);
cipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey(), secureRandom);
return cipher.doFinal(data);
}
public byte[] decryptWithHsm(String keyAlias, byte[] encryptedData)
throws GeneralSecurityException {
PrivateKey privateKey = (PrivateKey) hsmKeyStore.getKey(keyAlias, "".toCharArray());
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", hsmProvider);
cipher.init(Cipher.DECRYPT_MODE, privateKey, secureRandom);
return cipher.doFinal(encryptedData);
}
public String generateKeyInHsm(String keyAlias, String algorithm, int keySize)
throws GeneralSecurityException {
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm, hsmProvider);
keyGen.init(keySize, secureRandom);
SecretKey secretKey = keyGen.generateKey();
// Store in HSM
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
KeyStore.ProtectionParameter protection =
new KeyStore.PasswordProtection("".toCharArray());
hsmKeyStore.setEntry(keyAlias, secretKeyEntry, protection);
return keyAlias;
}
public byte[] wrapKey(String wrappingKeyAlias, String keyToWrapAlias)
throws GeneralSecurityException {
Key wrappingKey = hsmKeyStore.getKey(wrappingKeyAlias, "".toCharArray());
Key keyToWrap = hsmKeyStore.getKey(keyToWrapAlias, "".toCharArray());
Cipher cipher = Cipher.getInstance("AESWrap", hsmProvider);
cipher.init(Cipher.WRAP_MODE, wrappingKey, secureRandom);
return cipher.wrap(keyToWrap);
}
public Key unwrapKey(String wrappingKeyAlias, byte[] wrappedKey,
String algorithm, int keyType)
throws GeneralSecurityException {
Key wrappingKey = hsmKeyStore.getKey(wrappingKeyAlias, "".toCharArray());
Cipher cipher = Cipher.getInstance("AESWrap", hsmProvider);
cipher.init(Cipher.UNWRAP_MODE, wrappingKey, secureRandom);
return cipher.unwrap(wrappedKey, algorithm, keyType);
}
private char[] getHsmPin() {
// In production, this should come from a secure source:
// 1. Secure boot configuration
// 2. Hardware security module
// 3. Trusted platform module
// 4. Secure element
// For demo purposes
return "hsm-pin-123".toCharArray();
}
private X509Certificate generateSelfSignedCertificate(KeyPair keyPair, String cn)
throws GeneralSecurityException {
try {
// Generate X.509 certificate
X500Name issuer = new X500Name("CN=" + cn + ", O=Secure Bootstrap, C=US");
BigInteger serial = new BigInteger(64, secureRandom);
Date notBefore = new Date();
Date notAfter = new Date(notBefore.getTime() + 365L * 24 * 60 * 60 * 1000);
X500Name subject = issuer;
X509CertInfo certInfo = new X509CertInfo();
certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serial));
certInfo.set(X509CertInfo.ALGORITHM_ID,
new CertificateAlgorithmId(AlgorithmId.get("SHA256withRSA")));
certInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(subject));
certInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
certInfo.set(X509CertInfo.VALIDITY, new CertificateValidity(notBefore, notAfter));
certInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(issuer));
// Add key usage
boolean[] keyUsage = new boolean[9];
keyUsage[0] = true; // digitalSignature
keyUsage[2] = true; // keyEncipherment
keyUsage[5] = true; // keyCertSign
certInfo.set(X509CertInfo.KEY_USAGE, new KeyUsage(keyUsage));
// Sign certificate
X509CertImpl cert = new X509CertImpl(certInfo);
cert.sign(keyPair.getPrivate(), "SHA256withRSA");
return cert;
} catch (Exception e) {
throw new GeneralSecurityException("Failed to generate certificate", e);
}
}
}
3. Root of Trust Establishment
Secure Bootstrapper Core
```java
package com.secure.bootstrap.trust.chain;
import com.secure.bootstrap.hardware.tpm.TpmService;
import com.secure.bootstrap.hardware.hsm.HsmService;
import com.secure.bootstrap.crypto.keys.KeyManager;
import com.secure.bootstrap.configuration.secureloader.SecureConfigLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.security.; import java.security.cert.;
import java.util.*;
@Component
public class RootOfTrustBootstrap {
private static final Logger logger = LoggerFactory.getLogger(RootOfTrustBootstrap.class);
private final TpmService tpmService;
private final HsmService hsmService;
private final KeyManager keyManager;
private final SecureConfigLoader configLoader;
private boolean bootstrapped = false;
private TrustChain trustChain;
private PlatformAttestation platformAttestation;
public RootOfTrustBootstrap(TpmService tpmService, HsmService hsmService,
KeyManager keyManager, SecureConfigLoader configLoader) {
this.tpmService = tpmService;
this.hsmService = hsmService;
this.keyManager = keyManager;
this.configLoader = configLoader;
}
public synchronized BootstrapResult bootstrap() throws BootstrapException {
if (bootstrapped) {
return new BootstrapResult(true, "Already bootstrapped", trustChain);
}
try {
logger.info("Starting secure bootstrap process...");
// Phase 1: Hardware Root of Trust
logger.info("Phase 1: Establishing Hardware Root of Trust");
HardwareTrust hardwareTrust = establishHardwareTrust();
// Phase 2: Platform Attestation
logger.info("Phase 2: Platform Attestation");
platformAttestation = performPlatformAttestation(hardwareTrust);
// Phase 3: Certificate Chain Establishment
logger.info("Phase 3: Establishing Certificate Chain");
trustChain = establishTrustChain(platformAttestation);
// Phase 4: Secure Configuration Loading
logger.info("Phase 4: Loading Secure Configuration");
loadSecureConfiguration(trustChain);
// Phase 5: Service Identity Establishment
logger.info("Phase 5: Establishing Service Identity");
establishServiceIdentity(trustChain);
bootstrapped = true;
BootstrapResult result = new BootstrapResult(
true,
"Secure bootstrap completed successfully",
trustChain
);
logger.info("Secure bootstrap completed successfully");
return result;
} catch (Exception e) {
logger.error("Secure bootstrap failed", e);
throw new BootstrapException("Bootstrap failed: " + e.getMessage(), e);
}
}
private HardwareTrust establishHardwareTrust() throws BootstrapException {
HardwareTrust hardwareTrust = new HardwareTrust();
try {
// Initialize TPM
tpmService.initialize();
hardwareTrust.setTpmAvailable(true);
hardwareTrust.setTpmInitialized(true);
// Initialize HSM (if available)
try {
hsmService.generateRootKey("bootstrap-root", "Secure Bootstrap Root Key");
hardwareTrust.setHsmAvailable(true);
} catch (Exception e) {
logger.warn("HSM not available, continuing with TPM only");
hardwareTrust.setHsmAvailable(false);
}
// Generate hardware-backed random seed
SecureRandom hwRandom = SecureRandom.getInstanceStrong();
byte[] hwRandomSeed = hwRandom.generateSeed(64);
hardwareTrust.setHardwareRandomSeed(hwRandomSeed);
// Verify hardware security module properties
verifyHardwareSecurityProperties(hardwareTrust);
return hardwareTrust;
} catch (Exception e) {
throw new BootstrapException("Failed to establish hardware trust", e);
}
}
private PlatformAttestation performPlatformAttestation(HardwareTrust hardwareTrust)
throws BootstrapException {
try {
PlatformAttestation attestation = new PlatformAttestation();
// Generate TPM-based platform attestation
AttestationData tpmAttestation = tpmService.generatePlatformAttestation();
attestation.setTpmAttestation(tpmAttestation);
// Measure boot components
BootIntegrityMeasurement bootMeasurement = measureBootIntegrity();
attestation.setBootMeasurement(bootMeasurement);
// Verify platform state against known good measurements
boolean platformValid = verifyPlatformState(attestation);
if (!platformValid) {
throw new BootstrapException("Platform integrity verification failed");
}
// Generate platform identity
String platformIdentity = generatePlatformIdentity(attestation);
attestation.setPlatformIdentity(platformIdentity);
// Sign platform identity with hardware key
byte[] identitySignature = signPlatformIdentity(platformIdentity, hardwareTrust);
attestation.setIdentitySignature(identitySignature);
logger.info("Platform attestation completed. Identity: {}", platformIdentity);
return attestation;
} catch (Exception e) {
throw new BootstrapException("Platform attestation failed", e);
}
}
private TrustChain establishTrustChain(PlatformAttestation attestation)
throws BootstrapException {
try {
TrustChain chain = new TrustChain();
// Generate root CA certificate
X509Certificate rootCa = generateRootCertificate(attestation);
chain.setRootCertificate(rootCa);
// Generate intermediate certificates
List<X509Certificate> intermediates = generateIntermediateCertificates(rootCa);
chain.setIntermediateCertificates(intermediates);
// Generate service certificate
X509Certificate serviceCert = generateServiceCertificate(
intermediates.get(intermediates.size() - 1),
attestation.getPlatformIdentity()
);
chain.setServiceCertificate(serviceCert);
// Build certificate path
List<X509Certificate> certPath = new ArrayList<>();
certPath.add(serviceCert);
certPath.addAll(intermediates);
certPath.add(rootCa);
chain.setCertificatePath(certPath);
// Seal private keys in TPM/HSM
sealPrivateKeys(chain);
// Verify complete chain
boolean chainValid = verifyTrustChain(chain);
if (!chainValid) {
throw new BootstrapException("Trust chain verification failed");
}
logger.info("Trust chain established with {} certificates", certPath.size());
return chain;
} catch (Exception e) {
throw new BootstrapException("Failed to establish trust chain", e);
}
}
private void loadSecureConfiguration(TrustChain trustChain) throws BootstrapException {
try {
// Load initial configuration with hardware-backed encryption
byte[] encryptedConfig = configLoader.loadEncryptedConfiguration();
// Decrypt using TPM-sealed key
byte[] configKey = tpmService.unsealSecret(encryptedConfig);
// Apply configuration
Map<String, String> configuration = configLoader.parseConfiguration(configKey);
configLoader.applyConfiguration(configuration);
// Verify configuration integrity
boolean configValid = configLoader.verifyConfigurationIntegrity(configuration);
if (!configValid) {
throw new BootstrapException("Configuration integrity check failed");
}
logger.info("Secure configuration loaded successfully");
} catch (Exception e) {
throw new BootstrapException("Failed to load secure configuration", e);
}
}
private void establishServiceIdentity(TrustChain trustChain) throws BootstrapException {
try {
// Generate service identity token (JWT)
String serviceToken = generateServiceToken(trustChain);
// Register with service registry
registerWithServiceRegistry(serviceToken, trustChain);
// Establish secure channels
establishSecureChannels(trustChain);
logger.info("Service identity established");
} catch (Exception e) {
throw new BootstrapException("Failed to establish service identity", e);
}
}
// Helper methods
private void verifyHardwareSecurityProperties(HardwareTrust hardwareTrust)
throws BootstrapException {
// Verify TPM properties
// Verify HSM properties
// Check for secure boot
// Verify memory protection
// Check for debug interfaces
}
private BootIntegrityMeasurement measureBootIntegrity() {
BootIntegrityMeasurement measurement = new BootIntegrityMeasurement();
// Measure boot components
// Verify signatures
// Check integrity
return measurement;
}
private boolean verifyPlatformState(PlatformAttestation attestation) {
// Compare against known good measurements
// Check for tampering
// Verify signatures
return true;
}
private String generatePlatformIdentity(PlatformAttestation attestation)
Advanced Java Container Security, Sandboxing & Trusted Runtime Environments
https://macronepal.com/blog/sandboxing-java-applications-implementing-landlock-lsm-for-enhanced-container-security/
Explains using Linux Landlock LSM to sandbox Java applications by restricting file system and resource access without root privileges, improving application-level isolation and reducing attack surface.
https://macronepal.com/blog/gvisor-sandbox-integration-in-java-complete-guide/
Explains integrating gVisor with Java to provide a user-space kernel sandbox that intercepts system calls and isolates applications from the host operating system for stronger security.
https://macronepal.com/blog/selinux-for-java-mandatory-access-control-for-jvm-applications/
Explains how SELinux enforces Mandatory Access Control (MAC) policies on Java applications, strictly limiting what files, processes, and network resources the JVM can access.
https://macronepal.com/java/a-comprehensive-guide-to-intel-sgx-sdk-integration-in-java/
Explains Intel SGX integration in Java, allowing sensitive code and data to run inside secure hardware enclaves that remain protected even if the OS is compromised.
https://macronepal.com/blog/building-a-microvm-runtime-with-aws-firecracker-in-java-a-comprehensive-guide/
Explains using AWS Firecracker microVMs with Java to run workloads in lightweight virtual machines that provide strong isolation with near-container performance efficiency.
https://macronepal.com/blog/enforcing-mandatory-access-control-implementing-apparmor-for-java-applications/
Explains AppArmor security profiles for Java applications, enforcing rules that restrict file access, execution rights, and system-level permissions.
https://macronepal.com/blog/rootless-containers-in-java-secure-container-operations-without-root/
Explains running Java applications in rootless containers using Linux user namespaces so containers operate securely without requiring root privileges.
https://macronepal.com/blog/unlocking-container-security-harnessing-user-namespaces-in-java/
Explains Linux user namespaces, which isolate user and group IDs inside containers to improve privilege separation and enhance container security for Java workloads.
https://macronepal.com/blog/secure-bootstrapping-in-java-comprehensive-trust-establishment-framework/
Explains secure bootstrapping in Java, focusing on how systems establish trust during startup using secure key management, identity verification, and trusted configuration loading.
https://macronepal.com/blog/securing-java-applications-with-chainguard-wolfi-a-comprehensive-guide-2/
Explains using Chainguard/Wolfi minimal container images to secure Java applications by reducing unnecessary packages, minimizing vulnerabilities, and providing a hardened runtime environment.