Crypto without NIFs¶
JErlang does not implement NIFs. OTP's crypto, ssl and much of public_key
are built on the crypto NIF, so loading those modules is not the same as
having working crypto. The practical replacement is not a compatibility shim:
it is an explicit call from Erlang to the JVM's security APIs through the
java module.
The crypto-java example shows the
smallest useful version. It compiles this module with JErlang and runs it in a
JVM with no Erlang installation:
sha256_hex(Data) ->
Digest = java:call_static("java.security.MessageDigest", "getInstance",
["SHA-256"]),
try
hex(java:call(Digest, "digest", [Data]))
after
java:release(Digest)
end.
hmac_sha256_hex(Key, Data) ->
KeySpec = java:new("javax.crypto.spec.SecretKeySpec",
[Key, "HmacSHA256"]),
Mac = java:call_static("javax.crypto.Mac", "getInstance",
["HmacSHA256"]),
try
java:call(Mac, "init", [KeySpec]),
hex(java:call(Mac, "doFinal", [Data]))
after
java:release(Mac),
java:release(KeySpec)
end.
byte[] crosses the boundary as an Erlang binary, so the existing value mapping
does the work. The example also calls SecureRandom.generateSeed/1 and turns
the result into hex.
What can realistically be covered¶
| Need | Java route | Status |
|---|---|---|
| SHA-1, SHA-256, SHA-384, SHA-512, MD5 | java.security.MessageDigest |
Works in the example |
| HMAC | javax.crypto.Mac + SecretKeySpec |
Works in the example |
| Secure random bytes | java.security.SecureRandom |
Works in the example |
AES, ChaCha20 and other Cipher algorithms |
javax.crypto.Cipher, SecretKeySpec, GCMParameterSpec |
Possible application code; not exercised here |
| PBKDF2 and other key derivation | SecretKeyFactory |
Possible application code; not exercised here |
| RSA/ECDSA signatures | java.security.Signature, KeyFactory |
Possible, but key and ASN.1 handling is application work |
| X.509 parsing | CertificateFactory, X509Certificate |
Possible as Java objects; not OTP public_key terms |
| TLS client/server sockets | javax.net.ssl.SSLSocket / SSLServerSocket |
A separate Java networking path, not OTP ssl |
These are real JVM primitives, and a service that only needs a hash or a MAC can use them without waiting for NIF support. The cost is that the Erlang code is now coupled to Java class names and exception shapes, and it must release every object handle it creates.
What this cannot cover¶
- OTP module compatibility. Code that calls
crypto:hash/2,crypto:mac/3,public_key:verify/5orssl:connect/3still needs those modules, and those modules still need the NIF implementation. This example does not make them load. - TLS distribution. JErlang's distribution protocol is plain TCP with the
cookie handshake. Calling
SSLSocketin application code does not change that. - OTP certificate and key semantics.
public_keyrepresents keys and certificates as OTP records and supports OTP's PEM/DER handling. The Java route exposes Java objects instead. Converting between the two is an application-level format bridge, not a drop-in replacement. - Constant-time and side-channel guarantees. The JDK primitives make their own guarantees; this example does not add a constant-time comparison or audit the JVM provider.
- NIF ABI and precompiled dependencies. A precompiled NIF
.so/.dllstill cannot be loaded. Only the operations explicitly wrapped through Java are available.
Run it¶
Expected output includes:
sha256("abc") = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
hmac_sha256("Jefe", message) = 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
The test is part of CI, so a change to the Java interop conversion path that breaks binary arguments or byte-array results fails the build. It does not pretend to be a crypto conformance suite.