GithubHelp home page GithubHelp logo

sfuhrm / openssl4j Goto Github PK

View Code? Open in Web Editor NEW
22.0 3.0 4.0 505 KB

High performance Java crypto binding to the native OpenSSL library

License: Apache License 2.0

Makefile 2.21% Java 79.69% C 15.18% Shell 2.06% Dockerfile 0.86%
openssl java jni fast java-library security md5 ripemd160 sha1 sha256

openssl4j's Introduction

OpenSSL4J JNI Java Library

Single-Platform Build Java Build Crossplatform Build Maven Central License

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.

Features

  • Performance: The main feature of OpenSSL4J is performance: The MD5-implementation of OpenSSL4J is typically 67% to 102% faster than the pure Java version from SUN.
  • Functionality: There are some algorithms available in OpenSSL4J that are not available in the normal SUN crypto provider.

Performance

The following picture shows a performance comparison of

  • BouncyCastle crypto provider (version 1.70)
  • Adoptium JDK SUN crypto provider (JDK 17.0.6)
  • OpenSSL4j (version 0.3.0)

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.

bc-sun-ossl-performance.png

The benchmark was conducted on a i7-3840QM CPU.

Building OpenSSL4J for your platform

For building the application you need

  • JDK 8+,
  • Apache Maven,
  • GNU Make,
  • GNU GCC,
  • OpenSSL development headers

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] ------------------------------------------------------------------------    

Building OpenSSL4J for cross-platform

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:

  • DOCKERHUB_USERNAME: Dockerhub username for getting the parent of the build image.
  • DOCKERHUB_TOKEN: Dockerhub secret token.
  • GH_USER: Github username for storing artifacts.
  • GH_PASSWORD: Github password for storing artifacts.
  • SONATYPE_USER: (optional) sonatype username for pushing snapshots.
  • SONATYPE_PASSWORD: (optional) sonatype password for pushing snapshots.

(Date of last update: 2023-05-28)

Restrictions

  • MessageDigest restriction: The current milestone only contains MessageDigest algorithms.
  • Restricted platforms: The code uses dynamic linking to an object library on the machine. Native object code within the JAR file is used for binding the Java code to the native code. There is a restricted amount of platforms supported by the Github Actions builder (see below).

Usage

Dynamic security provider configuration

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();

Installing it in the JDK

You can also install the provider in your JDK installation. Open the java.security file in an editor:

  • Linux, or macOS: <java-home>/conf/security/java.security
  • Windows: <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
...

Including it with Maven

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>

Native platforms supported

There are the following native implementations available inside the JAR file:

  • Linux-aarch64
  • Linux-amd64
  • Linux-arm
  • Linux-ppc64le
  • Linux-s390x

Version notice

Please note that the current version is experimental.

Versions

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.

Author

Written 2020-2023 by Stephan Fuhrmann. You can reach me via email to s (at) sfuhrm.de

License

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.

openssl4j's People

Contributors

adarcanum avatar dependabot[bot] avatar sfuhrm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

openssl4j's Issues

Dynamic linking fails with libssl3.so systems

Hi, I created following project - https://github.com/adarcanum/openssl4j-example/tree/master
When running the main method it throws:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /tmp/native5689319720219818901/libopenssl4j-Linux-amd64.so: libssl.so.1.1: cannot open shared object file: No such file or directory
	at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
	at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:388)
	at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:232)
	at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:174)
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2389)
	at java.base/java.lang.Runtime.load0(Runtime.java:755)
	at java.base/java.lang.System.load(System.java:1953)
	at de.sfuhrm.openssl4j.NativeLoader.load(NativeLoader.java:48)
	at de.sfuhrm.openssl4j.NativeLoader.loadAll(NativeLoader.java:39)
	at de.sfuhrm.openssl4j.OpenSSL4JProvider.<init>(OpenSSL4JProvider.java:34)
	at com.example.MainKt.main(Main.kt:8)
	at com.example.MainKt.main(Main.kt)

Not sure what I might be missing here. Help would be appriciated.

EDIT: just for some context I tried doing some debugging, I can see the temp file created and libopenssl4j-Linux-amd64.so is inside, so I am not sure why it may be failing like this.

Fix cross platform build for JDK 17

For JDK 17, the build triggers an int64 problem for platforms of different endianess when executing the file build-helper/OsArch.java and creating the C headers from the Java files.

The C files generated by the JDK are portable, so I presume they can be generated before the C compilation on another platform.

Github actions build broken

# Created at 2023-05-28T10:49:34.029
/opt/hostedtoolcache/Java_Adopt_jdk/11.0.19-7/x64/bin/java: symbol lookup error: /tmp/native1164465476988834680/libopenssl4j-Linux-amd64.so: undefined symbol: EVP_CIPHER_do_all

Check code on Mac M1

There was a report that the new os property check breaks on M1 MACs.

  | // for (int i = 0; i < value.length(); i++) {
-- | --
  | //     final int c = value.charAt(i);
  | //     if ((!Character.isLetterOrDigit(c))) {
  | //         throw new IllegalStateException("os property '" + property + "' contains non-alphanumeric values. Char: " + c + " Original: " + value);
  | //     }
  | // }


Would you consider downgrading the build requirement to Java 8?

There are only three places in the code that use Java 9+ language features.

Two of them are due to using Set.of, which can be eplaced by new HashSet<>(Arrays.asList()) at a small cost to readability.

The other is because you are calling java.security.Provider(String name, String versionStr, String info) in OpenSSL4JProvider's constructor, but the overload with String versionStr wasn't added until Java 9.

We are unfortunately unable to use anything newer than Java 8.

Windows support

Would it be possible to also include a native library for Windows?

Add symmetric cipher algorithms

I've begun CIPHER implementation in the CIPHER branch.
It is just the beginning of the implementation and was moved to a branch after it broke the build (see #6).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.