If additional encryption is desired, symmetric encryption using the fernet specification is available.
Why Fernet?
Fernet builds on best practice cryptography methods, and allows developers to provide a simple method of encrypting and authenticating.
Conceptually, fernet takes a user-provided message (an arbitrary sequence of bytes), a key (256 bits), and the current time, and produces a token, which contains the message in a form that can't be read or altered without the key. Overall it uses 128-bit AES symmetric encryption in a CBC mode with PKCS7 padding and HMAC using SHA256 for authentication.
How to enable encryption
Encryption keys will be set-up during the initial calibration phase with a Unit21 engineer.
Header | Type | Elaboration |
---|---|---|
u21-fernet | String | Include if encryption is desired |
This additional encryption is available for all APIs. The steps to enable encryption are as follows:
- Include
u21-fernet : true
in the request header - Encrypt the payload (e.g. json) using the key
- Decrypt the payload response using the key
Example:
Language | Library Required |
---|---|
Python | Cryptography |
Java | Fernet-Java8 |
Javascript | Fernet |
import requests
from cryptography.fernet import Fernet
fernet = Fernet(b'<pre-shared-fernet-key>')
encrypted_data = fernet.encrypt(b'{"key": "value"}')
res = requests.post(
"https://<API_ENDPOINT>/v1/entities/create",
headers={'u21-key': '<YOUR_API_KEY>', 'u21-fernet': 'True'},
data=encrypted_data)
decrypted_ciphertext = fernet.decrypt(res.content)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.macasaet.fernet.Key;
import com.macasaet.fernet.StringValidator;
import com.macasaet.fernet.Token;
import com.macasaet.fernet.Validator;
public class EncryptionSample {
private final static HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build();
private static void sendPost() throws Exception {
String json = "{\"key\": \"value\"}";
final Key key = new Key("<pre-shared-fernet-key>");
final Token token = Token.generate(key, json);
HttpRequest request = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString(token.serialise()))
.uri(URI.create("https://<API_ENDPOINT>/v1/entities/create"))
.setHeader("u21-key", "<YOUR_API_KEY>")
.header("Content-Type", "application/json")
.header("u21-fernet", "True")
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
final Token tokenResult = Token.fromString(response.body());
final Validator<String> validator = new StringValidator() {};
System.out.println(tokenResult.validateAndDecrypt(key, validator));
}
public static void main (String[] args) throws Exception {
sendPost();
}
}
const axios = require('axios')
var fernet = require('fernet')
const headers = {
'u21-key': '<YOUR_API_KEY>',
'u21-fernet': 'True'
}
fernet.setSecret(<pre-shared-fernet-key>);
const token = new fernet.Token({ time: Date.now() });
const message = token.encode("Message");
axios
.post('https://<API_ENDPOINT>/v1/entities/create', {
headers: headers,
message
})
.then(res => {
var token = new fernet.Token({
secret: <pre-shared-fernet-key>,
token: res.data,
ttl: 0
})
token.decode();
})
.catch(error => {
console.error(error)
})