Decrypt data while indexing

Hello,
I want to search on encrypted data,and i use hibernate search for searching.
So, I need to decry pt the encrypted data. to be able to search on the real data.
Could you help, how can i make decryption while indexing ?

Hello,

Two things here:

  1. You need to decrypt the data that is encrypted in your database. To help you with that, we need to know how you encrypted your data.
  2. You probably also need to encpypt your index. The best solution for that is probably to encrypt your filesystem, as explained here.

Hello @yrodiere,
Thanks for your fast response.I will use an algorithm which will encrypt the database.
It is simple. just uses a key for encryption and decryption.
So i need to implement this algorithm while indexing data to do decryption function.

I think you should pick a concrete solution for encryption/decryption in your database.

Get to the point you can give us a snippet of code showing how you decrypt your data, then I may be able to tell you how to use that in Hibernate Search.

Until you get there, there are simply too many unkowns and I cannot help you.

Hello @yrodiere,
kindly check code below which is responsible for encryption / decryption

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class Encryptor {
    public static String encrypt(String key, String initVector, String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes());
            System.out.println("encrypted string: "
                    + Base64.encodeBase64String(encrypted));

            return Base64.encodeBase64String(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

    public static String decrypt(String key, String initVector, String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

            byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));

            return new String(original);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

    public static void main(String[] args) {
        String key = "Bar12345Bar12345"; // 128 bit key
        String initVector = "RandomInitVector"; // 16 bytes IV

        System.out.println(decrypt(key, initVector,
                encrypt(key, initVector, "Hello World")));
    }
}

Ok. Should I understand that you call encrypt before calling a setter on your entity, and decrypt on the value returned by the getter?

If you can, I would suggest to slightly change your approach and use an AttributeConverter instead, which would perform the encryption/decryption transparently: the data would be encrypted in your database and SQL queries, but it would be available in clear text in your entity. Then you wouldn’t need to do anything in Hibernate Search. See here for more details about attribute converters.

If you really want to encrypt/decrypt explicitly, you will need to implement a FieldBridge. See here for more information about field bridges.

Whatever solution you choose, you will probably need to inject the encryption key and initVector into the AttributeConverter or FieldBridge. If you can’t access this information through static methods, the only solution will be for you to define the converter/bridge as a Spring or CDI component; Hibernate ORM/Search will retrieve it from Spring/CDI, and the @Autowire/@Inject annotations will work as usual.
Obviously that can only work if you use Spring or CDI, and only if you use a Spring version/CDI vendor that added support for dependency injection within Hibernate ORM. Spring 5 should work fine, as well as WildFly 14+.