Encryption of variables in a cloud environment

@thorben @Webcyberrob @nicolas

Here is a example I just cleaned up and pulled from some previous work:



The example if simplified for demonstration purposes. In practice you would add things like external key files, and more configuration options.

I have also shown two different styles of Java object access with the Java.type() vs the direct class names.

Seal Test task is execution some javascript as follows:

//------------------------------------------------------------
var SealedObject = Java.type('javax.crypto.SealedObject')
var Cipher = Java.type('javax.crypto.Cipher')

var keyGenerator = javax.crypto.KeyGenerator.getInstance("DES");
var desKey = keyGenerator.generateKey();

var desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
desCipher.init(Cipher.ENCRYPT_MODE, desKey);

// Gets the Base64/String representation of the Key that was generated
function getKeyAsString(){
  var encodedKey = java.util.Base64.getEncoder().encodeToString(desKey.getEncoded());
  return encodedKey
}

// Generates a new Key (equiv to the desCipher object)
function buildKey(encodedKey){
  var decodedKey = java.util.Base64.getDecoder().decode(encodedKey);
  var originalKey = new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, "DES"); 
  return originalKey
}

// Generates a SealedObject with the default desCipher 
function seal(serialObject){
  var so = new SealedObject(serialObject, desCipher); 
  return so
}
//------------------------------------------------------------
/*
Reference Docs:
1. https://docs.oracle.com/javase/8/docs/api/javax/crypto/SealedObject.html
2. https://docs.oracle.com/javase/8/docs/api/javax/crypto/spec/SecretKeySpec.html
3. https://docs.oracle.com/javase/8/docs/api/javax/crypto/SecretKey.html
4. https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html
*/


// Generate a generic SPIN object for encryption demonstration
var myJsonToEncrypt = {
  "mykey":"my secret text"
}
var mySpinToEncrypt = S(JSON.stringify(myJsonToEncrypt))
var mySpinStringToEncrypt = mySpinToEncrypt.toString()
execution.setVariable('original_object', mySpinStringToEncrypt)

// Generate SealedObject from SPIN String
var sealed = seal(mySpinStringToEncrypt)
execution.setVariable('sealed_object',sealed)

// Get the Encoded Key
// In practice you can swap this out for uses of Certificates and Key files
var encodedkey = getKeyAsString()
execution.setVariable('secret_key', encodedkey)

// Simulate Generating a new SecretKey object from the encodedKey
// Simulates generating a key based on the String/Base64 of the secret key
var newKey = buildKey(encodedkey)
var unsealed = sealed.getObject(newKey)
execution.setVariable('unsealed_object', unsealed)

In Practice you setup a js file as a series of functions to Seal and UnSeal objects, and you set the script to auto load the cipher/key from a external file/volume. So when you need the encryption abilities you just do something like:

load('classpath:sealObject.js')
var myData = ...
execution.setVariable('myEncryptedData', seal(myData))

and when you need the data:

load('classpath:sealObject.js')
var myData_encrypted = execution.getVariable('myEncryptedData')
var myData = unseal(myData_encrypted, getCipher())

Further detailed here: Process Variable Encryption (scripting)