High performance Java crypto binding to the native OpenSSL library
OpenSSL4J is a Java bridge to the native OpenSSL library.
On the Java side it’s offering the
conventional MessageDigest class. In the background the calls
will be translated to the native OpenSSL library with all its
optimizations:
On x86, the assembly code uses the CPUID instruction (see the
OPENSSL_ia32cap.pod manpage) to determine if various instructions (AES,
SSE, MMX, etc) are available and will use them if so. For other processors,
similar tests are performed if at all possible.
The following picture shows a performance comparison of
Each bar shows different throughputs in megabytes per second.
The per-bar throughputs contain multiple different test scenarios
regarding blocks sizes and data structures used for
data passing (byte, array, direct ByteBuffer, heap ByteBuffer).
The median of the tests is presented by a dark-blue horizontal line
within the bar. The 25% and 75% quantile make up the
area of the bars.
The benchmark was conducted on a i7-3840QM CPU.
For building the application you need
To build the C library for your current platform, wrap it into a maven artifact (openssl4j-objects), build the java parts (openssl4j), execute:
$ build.sh
...
[INFO] Reactor Summary for OpenSSL4J Parent 0.2.1-SNAPSHOT:
[INFO]
[INFO] OpenSSL4J Parent ................................... SUCCESS [ 0.953 s]
[INFO] OpenSSL4J JNI ...................................... SUCCESS [ 5.859 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.912 s
[INFO] Finished at: 2023-05-28T20:38:43+02:00
[INFO] ------------------------------------------------------------------------
The current cross-platform build is driven by github actions, using QEMU
to build different platform shared object library.
The github actions are visible to everyone.
For the cross-platform build to work with your fork, there
are some project secrets needed to be set in your
Github fork settings:
(Date of last update: 2023-05-28)
The following example show how to create a MD5 message digest instance with the
dynamically chosen security Provider:
import de.sfuhrm.openssl4j.OpenSSL4JProvider;
...
MessageDigest messageDigest = MessageDigest.getInstance("MD5", new OpenSSL4JProvider());
messageDigest.update("hello world!".getBytes(Charset.forName("ASCII")));
byte[] digest = messageDigest.digest();
You can also install the provider in your JDK installation. Open the java.security
file in an editor:
<java-home>/conf/security/java.security
<java-home>\conf\security\java.security
To be used effectively, insert it in front of the SUN provider. If this is how the original file looks:
security.provider.1=SUN
security.provider.2=SunRsaSign
security.provider.3=SunEC
security.provider.4=SunJSSE
security.provider.5=SunJCE
security.provider.6=SunJGSS
security.provider.7=SunSASL
security.provider.8=XMLDSig
security.provider.9=SunPCSC
...
then the new file could look like this after inserting and renumbering the entries:
security.provider.1=OpenSSL4J
security.provider.2=SUN
security.provider.3=SunRsaSign
security.provider.4=SunEC
security.provider.5=SunJSSE
security.provider.6=SunJCE
security.provider.7=SunJGSS
security.provider.8=SunSASL
security.provider.9=XMLDSig
security.provider.10=SunPCSC
...
The recommended way of including the library into your project is using maven:
<dependency>
<groupId>de.sfuhrm</groupId>
<artifactId>openssl4j</artifactId>
<version>0.5.0</version>
</dependency>
There are the following native implementations available inside the JAR file:
Please note that the current version is experimental.
The version numbers used by openssl4j
itself comply to the
semantic versioning schema.
Especially major version changes come with breaking API
changes.
The temporary internal openssl4j-objects
artifact is using
date-derived versions, but it is invisible to maven users.
Written 2020-2023 by Stephan Fuhrmann. You can reach me via email to s (at) sfuhrm.de
The project is licensed under Apache License 2.0 after excluding OpenSSL4j release v0.3.0.
The project was licensed under LGPL 3.0 until including OpenSSL4j release v0.3.0.