Pure Java, lightweight application-level field encryption for Spring Boot.
Transparent encrypt/decrypt on write/read, HMAC blind index for exact-match queries, multi-DEK envelope encryption with key rotation support, pluggable storage adapters (MongoDB included), and no libmongocrypt dependency.
- Add starter dependency.
- Configure a CMK provider (
lightcrypto.kms.providersfor local, or cloud KMS module). - Annotate fields with
@Encrypted. - Use repository methods normally; blind-index queries work for
blindIndex=truefields.
Deep docs are in docs:
- Configuration
- Encryption Behavior (nested/collection/mode/types)
- Architecture, Envelope, Storage Format, Rotation
- CMK Provider SPI
- Migration: introduce LCL to existing plaintext data
- Wiki
- Transparent field encryption with
@Encrypted - Symmetric algorithms:
AES_256_GCM,AES_256_CBC,SM4_GCM,SM4_CBC - Blind index query rewrite for exact-match queries
- Nested object and collection/map encryption
- Whole-object mode for container confidentiality
- Per-namespace multi-DEK vault with versioned
kidand Wire Format V1 self-describing blobs - Pluggable storage adapters (MongoDB adapter included; SPI for JDBC, Elasticsearch, etc.)
- Pluggable CMK providers (local, Azure Key Vault, Alibaba Cloud KMS)
- Observability: structured events, Micrometer metrics, Spring Boot Actuator health indicator
Define a single version placeholder in your pom first:
<properties>
<lcl.version>x.y.z</lcl.version>
</properties>How to get latest stable version:
- Check the Maven Central badge at the top of this README.
- Or open: https://central.sonatype.com/artifact/io.github.emmansun/lcl-spring-boot-starter
Add the starter dependency:
<dependency>
<groupId>io.github.emmansun</groupId>
<artifactId>lcl-spring-boot-starter</artifactId>
<version>${lcl.version}</version>
</dependency>
<!-- Storage adapter (required — choose one matching your Spring Boot version) -->
<!-- Spring Boot 3.x -->
<dependency>
<groupId>io.github.emmansun</groupId>
<artifactId>lcl-adapter-mongodb</artifactId>
<version>${lcl.version}</version>
</dependency>
<!-- Spring Boot 4.x (use -v4 variant) -->
<!--
<dependency>
<groupId>io.github.emmansun</groupId>
<artifactId>lcl-adapter-mongodb-v4</artifactId>
<version>${lcl.version}</version>
</dependency>
-->Adapter selection: Use
lcl-adapter-mongodbfor Spring Boot 3.x, orlcl-adapter-mongodb-v4for Spring Boot 4.x. Do not include both — only one adapter should be on the classpath.
The -v4 adapter depends on lcl-adapter-mongodb-core (shared classes compiled against SB3 baseline, binary compatible with SB4). No special exclusion configuration is needed.
# application.properties (SB4)
# SB4 renamed the MongoDB URI property (was spring.data.mongodb.uri)
spring.mongodb.uri=${MONGODB_URI:mongodb://localhost:27017/mydb}If your parent POM manages Spring Boot 3.x versions, import the SB4 BOM in your module's <dependencyManagement>:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>4.0.7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Cloud KMS modules:
<!-- Azure Key Vault -->
<dependency>
<groupId>io.github.emmansun</groupId>
<artifactId>lcl-provider-azure-kms</artifactId>
<version>${lcl.version}</version>
</dependency>
<!-- Alibaba Cloud KMS -->
<dependency>
<groupId>io.github.emmansun</groupId>
<artifactId>lcl-provider-alibaba-kms</artifactId>
<version>${lcl.version}</version>
</dependency>If you need snapshot builds, use GitHub Packages: https://github.com/emmansun/LightCrypto-Link/packages
Local symmetric CMK example:
lightcrypto:
kms:
providers:
- id: local
type: LOCAL_SYMMETRIC
key-hex: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
cryptography:
default-algorithm: AES_256_GCMSee full property references and cloud KMS examples: docs/configuration.md
@Document
public class User {
@Id
private String id;
private String name;
@Encrypted(blindIndex = true)
private String phone;
@Encrypted(algorithm = SymmetricAlgorithm.SM4_GCM)
private String idCard;
@Encrypted
private Integer age;
}userRepository.save(user);
User u = userRepository.findById(id).orElseThrow();
User found = userRepository.findByPhone("13800138001");Use ProgrammaticCryptoService for DTO/message encryption, migration scripts,
or manual decryption of raw query results.
Document encrypted = programmaticCryptoService.encryptValue("13800138000", User.class);
Object plain = programmaticCryptoService.decryptValue(encrypted);Key rotation API is:
keyVaultService.rotateDek("default.default.User#phone");For behavior details, see docs/architecture.md.
LCL provides built-in observability features (enabled by default):
All crypto operations emit structured events via EventBus:
{"event":"lcl.crypto.encrypt.completed","tier":"L2","result":"success","algorithm":"AES_256_GCM","durationMicros":240}When Micrometer is on the classpath, LCL registers timers and counters:
lcl.crypto.encrypt.duration/lcl.crypto.decrypt.durationlcl.rotation.duration/lcl.keyvault.load.durationlcl.crypto.encrypt.total/lcl.crypto.decrypt.total
When Spring Boot Actuator is on the classpath, LCL registers a HealthIndicator:
- UP — all components healthy
- OUT_OF_SERVICE — degraded
- DOWN — fatal error
lightcrypto:
observability:
enabled: true # master switch
events.enabled: true # structured logging
metrics.enabled: true # Micrometer metrics
health.enabled: true # Actuator healthSee docs/configuration.md for full reference.
LCL runs a self-diagnostic sequence at startup to verify cryptographic integrity before serving traffic:
| Phase | Check | Failure Class |
|---|---|---|
| BOOT-1 | Configuration validation | FATAL |
| BOOT-2 | SPI version check | FATAL |
| BOOT-4 | KAT (Known Answer Test) — AES-256-GCM, SM4-GCM, AES-256-CBC, SM4-CBC, HMAC-SHA-256, HKDF | FATAL |
| BOOT-8 | Vault reachability | RECOVERABLE |
| BOOT-9 | KMS reachability (wrap/unwrap canary key) | RECOVERABLE |
| BOOT-10 | Canary encrypt/decrypt roundtrip | FATAL |
When Spring Boot Actuator is on the classpath:
GET /actuator/lclhealth— bootstrap status, SDK version, component healthGET /actuator/lclkat— KAT results with per-algorithm timingPOST /actuator/lclkat— on-demand KAT re-run
lightcrypto:
runtime:
bootstrap-enabled: true # enable/disable bootstrap diagnostics
bootstrap-timeout: 15s # max time for full bootstrap sequenceSee lcl-examples for runnable demos:
# Spring Boot 3.x
cd lcl-examples/basic-crud
mvn spring-boot:run
# Spring Boot 4.x (requires MongoDB — inject URI via env)
cd lcl-examples/basic-crud-v4
set MONGODB_URI=mongodb://user:pass@host:27017/db?authSource=admin # Windows
export MONGODB_URI=mongodb://user:pass@host:27017/db?authSource=admin # Linux/macOS
mvn spring-boot:run
cd lcl-examples/azure-keyvault
mvn spring-boot:run
cd lcl-examples/alibaba-kms
mvn spring-boot:run
cd lcl-examples/observability
mvn spring-boot:run
# Then check: GET /actuator/health, GET /actuator/metrics/lcl.crypto.encryptgit clone https://github.com/emmansun/LightCrypto-Link.git
cd LightCrypto-Link
mvn clean verifyLightCrypto-Link/
|- lcl-spi/ # SPI contracts (CmkProvider, WrappedKey, VaultStore, StorageAdapter, QueryTransformer)
|- lcl-core/ # Pure crypto core (Wire Format V1, CryptoCodec, BlindIndexEngine, KCV)
|- lcl-adapter-mongodb-core/ # Shared MongoDB adapter classes (version-independent)
|- lcl-adapter-mongodb/ # MongoDB storage adapter — Spring Boot 3.x (query layer)
|- lcl-adapter-mongodb-v4/ # MongoDB storage adapter — Spring Boot 4.x (query layer)
|- lcl-spring-boot-starter/ # Core starter (annotation-driven encryption)
|- lcl-provider-azure-kms/ # Azure Key Vault CMK provider
|- lcl-provider-alibaba-kms/ # Alibaba Cloud KMS CMK provider
|- lcl-examples/ # Example applications
| |- basic-crud/ # Spring Boot 3.x
| |- basic-crud-v4/ # Spring Boot 4.x
| |- azure-keyvault/
| |- alibaba-kms/
| `- observability/
|- vectors/ # Golden test vectors (cross-language verification)
`- docs/