Introduction

The goal of the encryption service is to encrypt data that is being sent through Web Service miniApps. For example, you might want us to encrypt the data we are sending to the indicated endpoint. Or you might want us to decrypt the encrypted data we are getting from you. Below you can read how you can configure these options.

The encryption service operates using asymmetric encryption (public-key cryptography).

We encrypt your data with your public key, so only you have the key to decrypt it. How this is set up is described below.

Keep in mind that in order to access the Encryption functionality, you need to be assigned a specific role. For this, contact our Support.

Creating an Encryption Profile

The goal of an encryption profile is to store the keys you will need for encryption or decryption.

To create an Encryption Profile:

  1. Go to the Encryption Profiles tab and click Create.

  2. Insert your Encryption Profile Name and select Group from the drop-down list.

  3. Click Next.

4. Copy and paste your RSA public keys and click Create:

  • Encryption Key:

    • We use this key to encrypt data sent to you (decrypt cipher)

    • The algorithm used: RSA/ECB/OAEPWithSHA-512AndMGF1Padding

    • Java sample code to decrypt data on the customer side

  • Verification Key:

    • We use it to verify that the message received was signed with your private key (verify the signature)

    • The algorithm used: SHA512withRSA

5. In the next step, you will see the OCP pair of keys.

Save these keys somewhere safe.

You can use them to encrypt the data you are sending to OCP and sign messages that you send to use:

  • Encryption Key:

    • Use this key to encrypt messages send to Omilia

    • Algorithm used: RSAES_OAEP_SHA_256

    • Key Specification: RSA_4096

  • Signing Key:

    • Use this key to verify messages are sent from Omilia

    • Algorithm used: RSASSA_PSS_SHA_256

    • Key Specification: RSA_4096

6. Click Finish to save the encryption profile. You can always go back and update your keys or renew the OCP Encryption key if you feel that there has been a security incident.

The keys are renewed by Omilia once every year. You will be notified through email before this happens in order to update your systems.

In case you’ve lost the OCP Verification Key, please contact Support. This key is managed by the OCP team exclusively.

Using an Encryption Profile

To use your Encryption Profile, follow the steps below:

You can have different encryption profiles for each available environment mode (uat, dev, prod).

  1. Go to your Web Service miniApp where you want to use the encryption service.

  2. Go to the Web Services tab and select the encryption profile from the dropdown menu as shown in the screenshot below:

  3. Specify the values you want to be encrypted and signed the following way:

{
"creditCardNumber" : "{{extValue1|encrypt}}" - marks the field to be encrypted
"creditCardNumberSignature": "{{extValue1|sign}}" - marks the field to be signed
}

Form data
creditCardNumber→{{extValue1|encrypt}}

extValue1 gets populated during the session, as in the example above, it can be a credit card number the user named during the dialog session.

If you don’t add |encrypt, then the data will remain as it was (unencrypted).

Add decryption path

If you want Omilia to get the encrypted data from your endpoint and decrypt it when, for instance, announcing it to the user, proceed as follows:

  1. Go to Outputs → Decryption and click + Add decryption path:

2. The ID value you specify can be used in Fields → path, and then you will be able to use the output value in any other miniApp (such as Announcement miniApp, for example).

Encryption

Below you can find sample code in Java on how to encrypt data on the customer side using OCP Public Key from the encryption profile.

The following code snippet is just an example. Omilia does not accept any liability for any harm caused by using or misusing this code snippet!

@Slf4j
public class CryptoUtils {

    // constants
    private static final String ENCRYPTION_ALGORITHM = "RSA/ECB/OAEPWithSHA-512AndMGF1Padding";
    private static final String SIGNING_ALGORITHM = "SHA512withRSA";

    // default
    private CryptoUtils() {
        // private constructor
    }

    public static PublicKey getPublicKey(String base64PublicKey) {

        try {
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Utils.base64decode(base64PublicKey));
            return KeyFactory
                    .getInstance("RSA")
                    .generatePublic(keySpec);
        } catch (GeneralSecurityException e) {
            log.error("getPublicKey | GeneralSecurityException | {}", e.getMessage());
        }
        return null;
    }

    public static String encrypt(String plainText, String publicKey) {

        try {

            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey));
            return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)));
        } catch (GeneralSecurityException e) {
            log.error("getPublicKey | GeneralSecurityException | {}", e.getMessage());
        }
        return null;
    }

    public static boolean verify(String cipherText, String signature, String publicKey) {

        try {
            Signature publicSignature = Signature.getInstance(SIGNING_ALGORITHM);
            publicSignature.initVerify(getPublicKey(publicKey));
            publicSignature.update(cipherText.getBytes(StandardCharsets.UTF_8));
            return publicSignature.verify(
                    Base64.getDecoder().decode(signature)
            );
        } catch (GeneralSecurityException e) {
            log.error("verify | GeneralSecurityException | {}", e.getMessage());
        }
        return false;
    }
}
JAVA

Decryption

Below you can find sample code in Java on how to decrypt something on the customer side that was encrypted using the customer's OCP Public Key.

The following code snippet is just an example. Omilia does not accept any liability for any harm caused by using or misusing this code snippet!

package com.omilia.encryption.service.utils;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

@Slf4j
public class CryptoUtils {

    private static final String PARTY_B_ENCRYPTION_ALGORITHM = "RSA/ECB/OAEPWithSHA-512AndMGF1Padding";
    private static final String PARTY_B_SIGNING_ALGORITHM = "SHA512withRSA";

    public static PublicKey getPublicKey(String base64PublicKey) {

        try {
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Utils.base64decode(base64PublicKey));
            return KeyFactory
                    .getInstance("RSA")
                    .generatePublic(keySpec);
        } catch (GeneralSecurityException e) {
            log.error("getPublicKey | GeneralSecurityException | {}", e.getMessage());
        }
        return null;
    }

    public static PrivateKey getPrivateKey(String base64PrivateKey) {

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
                Utils.base64decode(base64PrivateKey)
        );
        try {

            return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
        } catch (GeneralSecurityException e) {
            log.error("getPrivateKey | GeneralSecurityException | {}", e.getMessage());
        }
        return null;
    }

    public static String encrypt(String plainText, String publicKey) {

        try {

            Cipher cipher = Cipher.getInstance(PARTY_B_ENCRYPTION_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey));
            return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)));
        } catch (GeneralSecurityException e) {
            log.error("getPublicKey | GeneralSecurityException | {}", e.getMessage());
        }
        return null;
    }

    public static String decrypt(String cipherText, String base64PrivateKey) throws GeneralSecurityException {

        Cipher cipher = Cipher.getInstance(PARTY_B_ENCRYPTION_ALGORITHM);
        cipher.init(
                Cipher.DECRYPT_MODE,
                getPrivateKey(base64PrivateKey)
        );
        return new String(
                cipher.doFinal(Utils.base64decode(cipherText))
        );
    }

    public static String sign(String plainText, PrivateKey privateKey) throws GeneralSecurityException {

        Signature privateSignature = Signature.getInstance(PARTY_B_SIGNING_ALGORITHM);
        privateSignature.initSign(privateKey);
        privateSignature.update(plainText.getBytes(StandardCharsets.UTF_8));
        byte[] signature = privateSignature.sign();
        return Base64.getEncoder().encodeToString(signature);
    }

    public static boolean verify(String cipherText, String signature, String publicKey) {

        try {
            Signature publicSignature = Signature.getInstance(PARTY_B_SIGNING_ALGORITHM);
            publicSignature.initVerify(getPublicKey(publicKey));
            publicSignature.update(cipherText.getBytes(StandardCharsets.UTF_8));
            return publicSignature.verify(
                    Base64.getDecoder().decode(signature)
            );
        } catch (GeneralSecurityException e) {
            log.error("verify | GeneralSecurityException | {}", e.getMessage());
        }
        return false;
    }
}
JAVA