All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mekuanent.encryption.handler.PBEHandler Maven / Gradle / Ivy

package com.github.mekuanent.encryption.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.validation.constraints.NotNull;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;


/**
 * A default Encryption Handler algorithm, which can only be assigned as global com.mekuanent.encryption handler
 * it uses PBEWithHmacSHA512AndAES_128 algorithm
 *
 * @author Mekuanent Kassaye
 */
public class PBEHandler implements IEncryptionHandler {

    private PBEParameterSpec ivSpec;
    private SecretKeySpec secret;
    private Exception ex;

    private static final Logger log = LoggerFactory.getLogger(PBEHandler.class);

    /**
     * Constructs PBEHandler with the following parameters
     * @param password choose a strong key for a better com.mekuanent.encryption
     * @param salt Salt for Encryption
     * @param iv IV for encryption
     * @param iteration the number of times the encryption has to iterated/layered
     */
    public PBEHandler(@NotNull char[] password, @NotNull byte[] salt, @NotNull byte[] iv,
                      int iteration) {
        this(password, salt, iv, iteration, 256);
    }

    /**
     * Constructs PBEHandler with the following parameters
     * @param password choose a strong key for a better com.mekuanent.encryption
     * @param salt salt for encryption
     * @param iv IV for encryption
     * @param derivedKeyLength the length of the salt + password combination key, default is 256
     * @param iteration the number of times the encryption has to iterated/layered
     */
    public PBEHandler(@NotNull char[] password, @NotNull byte[] salt, @NotNull byte[] iv,
                      int iteration, int derivedKeyLength) {

        try{
            KeySpec keySpec = new PBEKeySpec(password, salt, iteration, derivedKeyLength * 8);
            SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");

            SecretKey tmp = f.generateSecret(keySpec);
            secret = new SecretKeySpec(tmp.getEncoded(), "PBEWithHmacSHA512AndAES_128");

            ivSpec = new PBEParameterSpec(iv, 4096, new IvParameterSpec(new byte[16]));
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
            ex = e;
        }


    }

    /**
     * handles com.mekuanent.encryption of the provided text
     * @param raw raw input string
     * @return if successful encrypted base64 string otherwise {@literal null}, error messages will be printed if it is null
     */
    @Override
    public String encrypt(String raw) {

        if(ivSpec == null || secret == null){
            ex.printStackTrace();
            return null;
        }

        try {
            Cipher c = Cipher.getInstance("PBEWITHHMACSHA512ANDAES_128");
            c.init(Cipher.ENCRYPT_MODE, secret, ivSpec);
            byte[] cipherText = c.doFinal(raw.getBytes());

            return Base64.getEncoder().encodeToString(cipherText);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * handles decryption of the provided text
     * @param cipher encrypted base64 string
     * @return if successful decrypted string otherwise {@literal null}, error messages will be printed if it is null
     */
    @Override
    public String decrypt(String cipher) {

        try {
            Cipher c = Cipher.getInstance("PBEWithHmacSHA512AndAES_128");
            c.init(Cipher.DECRYPT_MODE, secret, ivSpec);
            byte[] rawText = c.doFinal(Base64.getDecoder().decode(cipher));
            return new String(rawText);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e){
            log.error("Decode Couldn't work because Last unit does not have enough valid bits, This usually happens when you have un encrypted data in your entity");
        }

        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy