Connected devices are no longer trusted just because they sit behind a firewall. A smart meter, a medical wearable or an industrial gateway has to prove who it is, keep its data confidential, detect tampering, and accept only firmware that was genuinely signed by its manufacturer. Regulations such as the EU Cyber Resilience Act are turning these “sometimes wrongly overlooked” properties into legal obligations.
But cryptography on embedded targets is hard to get right: the algorithms are numerous, the hardware accelerators differ from one SoC to the next, and a single mistake in a hand-rolled implementation can quietly defeat the whole security story.
How do you give application developers a familiar, safe way to do crypto, while still using the optimized engine that ships with your silicon? This is exactly what the MicroEJ Security library is for. In the next five minutes, we will walk through what it offers, how the Java API maps down to native crypto engines, and how it fits into your VEE Port.
A standard Java Cryptography API
The Security Foundation Library exposes a subset of the Java Cryptography Architecture (JCA/JCE) — the same java.security and javax.crypto APIs that millions of Java developers already know. There is nothing MicroEJ-specific to learn to start hashing, encrypting or verifying a signature.
The library groups cryptographic services into a handful of well-known engine classes:
MessageDigest— one-way hashing (e.g. SHA-256, SHA-512) for integrity checks and fingerprints.Mac— keyed message authentication codes (e.g. HMAC-SHA256) to prove both integrity and authenticity.Cipher— symmetric and asymmetric encryption/decryption (e.g. AES in CBC/GCM, RSA) for confidentiality.Signature— digital signatures (e.g. RSA, ECDSA) for authenticity and non-repudiation, the backbone of secure boot and signed updates.SecureRandom— a cryptographically strong random source, the foundation every key and nonce depends on.KeyFactory,KeyPairGenerator,SecretKeyFactory,KeyAgreement— to build, derive and exchange keys (e.g. RSA/EC key pairs, ECDH agreement).KeyStore— a container for keys and trusted certificates.
Each engine class is obtained through a factory method and then driven with a small, consistent lifecycle. For example, verifying that a piece of data matches a known SHA-256 digest:
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
sha256.update(payload);
byte[] digest = sha256.digest();
//you then use digest to compare to a validated preexisting digest/hash
Encrypting with AES looks just as familiar:
SecretKey key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));
byte[] ciphertext = cipher.doFinal(plaintext);
Because this is standard JCA, code written against it is portable: the same application logic runs on the simulator, on your device, and on any other devices.
Certificates and trust management
Confidentiality is only half the story — devices also need to know who they are talking to. The library therefore includes the java.security.cert package for X.509 certificate handling: parsing certificates with CertificateFactory, representing them as X509Certificate, and validating certificate chains against a set of trust anchors with CertPathValidator and the PKIX classes.
This is what allows a device to establish trust in a server (or a server to trust the device) and is the machinery that underpins mutual TLS. In fact, the Security library is the cryptographic foundation that the SSL/TLS library builds on to secure network connections.
The architecture: one API, any crypto engine
The strength of the offer is in how cleanly it separates what an application asks for from how the platform delivers it. The design is layered:
- Managed application — calls the standard JCA API (
Cipher,Signature, …). - Security library + “Crypto” provider — a MicroEJ JCA provider that routes each request to the right native operation.
- LLSEC Low-Level API — a thin native abstraction layer, exposed as C header files, that the application processor calls through SNI (Simple Native Interface).
- Native crypto engine — the actual implementation: Mbed TLS, OpenSSL, wolfSSL, EScrypt Cycur, PSA Crypto or a hardware crypto accelerator.
This means the managed code never changes when you swap the underlying engine. Choose a software cryptographic implementation on one product and a hardware accelerator on the next — the application is none the wiser.
How it ships and how to enable it
The Security library is distributed as part of the Net Pack, which bundles the Net, SSL and Security libraries together. To use it:
- On the VEE Port, add the dependency to the Net Pack then provide the LLSEC implementation backed by your crypto engine.
- In the application, declare a dependency on the
ej.api:securitymodule and program against the standard JCA API.
On the simulator, a mock provides the same crypto services on your development machine, so you can build and test security features long before the hardware is ready.
Going further
In five minutes you have seen that crypto on MicroEJ is, deliberately, not exotic: it is the standard Java Cryptography Architecture on top, an LLSEC abstraction in the middle, and a native engine underneath. You get a familiar and portable API for your developers, freedom to pick the best crypto engine for each product, and a solid foundation for TLS, secure boot and signed updates.
To dig deeper:
-
Security API module and its Javadoc reference — the full class reference for the
securitylibrary. -
VEE Porting Guide → Security — how to enable Security and implement the LLSEC Low-Level API for your crypto engine.
-
VEE Porting Guide → SSL — secure network communication built on top of Security.
-
Common Cryptographic Abstraction Layers: WolfCrypt, MbedTLS, Linux/OpenSSL, and Zephyr.
-
NET/Security Pack and VEE Port Integration Example: i.MX RT1170 VEE Port
Happy (and secure) coding!
— The MicroEJ Team
