Java Library

Step-by-step instructions for protecting data in your Java application

Overview

The Ubiq Security Java library provides convenient interaction with the Ubiq Security Platform API from applications written in the Java language. It includes a pre-defined set of classes that will provide simple interfaces to encrypt and decrypt data.

Installation

Requirements

Java 11 or later

Gradle Users

Add this dependency to your project's build file:

implementation group: 'com.ubiqsecurity', name: 'ubiqsecurity', version: 'latest.release'

Maven users

Add this dependency to your project's POM, where X.Y.Z represents the appropriate version number:

<dependency>
  <groupId>com.ubiqsecurity</groupId>
  <artifactId>ubiqsecurity</artifactId>
  <version>X.Y.Z</version>
</dependency>

Others

You'll need to manually install the following JARs:

Building from source:

Use following command to use [gradlew] to build the JAR file

Linux / Mac / Unix

./gradlew assemble build

Windows

.\gradlew assemble build

Requirements

  • OpenJDK 11 or later

Usage

Credentials

The library needs to be configured with your account credentials which are available in your Ubiq Dashboard credentials. The credentials can be hardcoded into your application, specified with environment variables, loaded from an explicit file, or loaded from a file in your home directory [~/.ubiq/credentials].

A. Production and Production-Like Use

❗️

In a production deployment, it is critical to maintain the secrecy of Ubiq API Key Credentials (SECRET_CRYPTO_ACCESS_KEY and SECRET_SIGNING_KEY) and API tokens (ACCESS_KEY_ID).

These items SHOULD be stored in a secrets management server or password vault. They should NOT be stored in a standard data file, embedded in source code, committed to a source code repository, or insecurely used in environmental variables.

After API Key Credentials are obtained from the security server or vault by the client application, the Ubiq API Key Credential values can then be passed to the Credentials() function as strings.

B. Development Use

During initial development of an application, it may be desirable to use a simpler, insecure mechanism to store Ubiq API Key Credentials. The sections below provide some examples.

Referencing the Ubiq Security library

Make sure your source files import these public types from the ubiqsecurity library:

import com.ubiqsecurity.UbiqCredentials;
import com.ubiqsecurity.UbiqDecrypt;
import com.ubiqsecurity.UbiqEncrypt;
import com.ubiqsecurity.UbiqFactory;

Read credentials from a specific file and use a specific profile

// This example is for development use only - Storing Ubiq API Key Credentials in a file is not recommended
UbiqCredentials credentials = UbiqFactory.readCredentialsFromFile("some-credential-file", "some-profile");

Read credentials from ~/.ubiq/credentials and use the default profile

// This example is for development use only - Storing Ubiq API Key credentials in a file is not recommended
UbiqCredentials credentials = UbiqFactory.readCredentialsFromFile("", "default");

Use the following environment variables to set the credential values

UBIQ_ACCESS_KEY_ID
UBIQ_SECRET_SIGNING_KEY
UBIQ_SECRET_CRYPTO_ACCESS_KEY

// This example is for development use only - Storing Ubiq API Key Credentials in environmental variables is not generally recommended
UbiqCredentials credentials = UbiqFactory.createCredentials(null, null, null, null);

Explicitly set the credentials

// This example is for development use only - Storing Ubiq API Key Credentials in source code is INSECURE!
UbiqCredentials credentials = UbiqFactory.createCredentials("<yourAccessKey>", "<yourSigningKey>", "<yourCryptoKey>", null);

Runtime exceptions

Unsuccessful requests raise exceptions. The exception object will contain the error details.

Encrypt a simple block of data

Pass credentials and plaintext bytes into the encryption function. The encrypted data
bytes will be returned.

import ubiqsecurity.UbiqCredentials;
import ubiqsecurity.UbiqEncrypt;

UbiqCredentials credentials = ...;
byte[] plainBytes = ...;
byte[] encryptedBytes = UbiqEncrypt.encrypt(credentials, plainBytes);

Decrypt a simple block of data

Pass credentials and encrypted data into the decryption function. The plaintext data
bytes will be returned.

import ubiqsecurity.UbiqCredentials;
import ubiqsecurity.UbiqDecrypt;

UbiqCredentials credentials = ...;
byte[] encryptedBytes = ...;
byte[] plainBytes = UbiqDecrypt.decrypt(credentials, encryptedBytes);

Encrypt a large data element where data is loaded in chunks

  • Create an encryption object using the credentials.
  • Call the encryption instance begin() method.
  • Call the encryption instance update() method repeatedly until all the data is processed.
  • Call the encryption instance end() method.

Here's the example code from the reference source:

static void piecewiseEncryption(String inFile, String outFile, UbiqCredentials ubiqCredentials)
        throws IOException, IllegalStateException, InvalidCipherTextException {
    try (FileInputStream plainStream = new FileInputStream(inFile)) {
        try (FileOutputStream cipherStream = new FileOutputStream(outFile)) {
            try (UbiqEncrypt ubiqEncrypt = new UbiqEncrypt(ubiqCredentials, 1)) {
                // start the encryption
                byte[] cipherBytes = ubiqEncrypt.begin();
                cipherStream.write(cipherBytes);

                // process 128KB at a time
                var plainBytes = new byte[0x20000];

                // loop until the end of the input file is reached
                int bytesRead = 0;
                while ((bytesRead = plainStream.read(plainBytes, 0, plainBytes.length)) > 0) {
                    cipherBytes = ubiqEncrypt.update(plainBytes, 0, bytesRead);
                    cipherStream.write(cipherBytes);
                }

                // finish the encryption
                cipherBytes = ubiqEncrypt.end();
                cipherStream.write(cipherBytes);
            }
        }
    }
}

Decrypt a large data element where data is loaded in chunks

  • Create a decryption object using the credentials.
  • Call the decryption instance begin() method.
  • Call the decryption instance update() method repeatedly until all data is processed.
  • Call the decryption instance end() method

Here's the example code from the reference source:

static void piecewiseDecryption(String inFile, String outFile, UbiqCredentials ubiqCredentials)
        throws FileNotFoundException, IOException, IllegalStateException, InvalidCipherTextException {
    try (FileInputStream cipherStream = new FileInputStream(inFile)) {
        try (FileOutputStream plainStream = new FileOutputStream(outFile)) {
            try (UbiqDecrypt ubiqDecrypt = new UbiqDecrypt(ubiqCredentials)) {
                // start the decryption
                byte[] plainBytes = ubiqDecrypt.begin();
                plainStream.write(plainBytes);

                // process 128KB at a time
                var cipherBytes = new byte[0x20000];

                // loop until the end of the input file is reached
                int bytesRead = 0;
                while ((bytesRead = cipherStream.read(cipherBytes, 0, cipherBytes.length)) > 0) {
                    plainBytes = ubiqDecrypt.update(cipherBytes, 0, bytesRead);
                    plainStream.write(plainBytes);
                }

                // finish the decryption
                plainBytes = ubiqDecrypt.end();
                plainStream.write(plainBytes);
            }
        }
    }
}