org.pepstock.jem.node.security.Crypto.java Source code

Java tutorial

Introduction

Here is the source code for org.pepstock.jem.node.security.Crypto.java

Source

/**
JEM, the BEE - Job Entry Manager, the Batch Execution Environment
Copyright (C) 2012-2015   Simone "Busy" Businaro
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.pepstock.jem.node.security;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMException;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
import org.pepstock.jem.log.LogAppl;
import org.pepstock.jem.log.MessageException;
import org.pepstock.jem.node.NodeMessage;
import org.pepstock.jem.util.CharSet;

/**
 * Common utility to work with keys for security.
 * 
 * @author Simone "Busy" Businaro
 * @version 1.0
 * 
 */
public class Crypto {

    private static final String DESEDE_ALGORITHM = "DESede";

    /**
     * To avoid any instantiation
     */
    private Crypto() {

    }

    /**
     * Loads a private key from a file, using password and file passed ar argument
     * 
     * @param pemKeyFile is the pem file of the RSA private key of the user.
     * @param password the password of the private key if the private key is
     *            protected by a password, null otherwise
     * @return the private Key read from pem file
     * @throws KeyException if any Exception occurs while extracting private key
     * @throws MessageException if any Exception occurs while extracting private key
     */
    public static Key loadPrivateKeyFromFile(File pemKeyFile, String password)
            throws MessageException, KeyException {
        try {
            // checks if the provider is loaded.
            // if not, it adds BouncyCastle as provider
            if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
                Security.addProvider(new BouncyCastleProvider());
            }
            // private key file in PEM format, from file
            PEMParser pemParser = new PEMParser(
                    new InputStreamReader(new FileInputStream(pemKeyFile), CharSet.DEFAULT));
            // reads the object and close the parser and input stream
            Object object = pemParser.readObject();
            pemParser.close();
            // creates a key converter by BouncyCastle
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
            // gets key pair instance
            KeyPair kp;
            // if is a PEM
            if (object instanceof PEMEncryptedKeyPair) {
                if (password == null) {
                    throw new MessageException(NodeMessage.JEMC205E);
                }
                // uses the PEM decryptor using password
                PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
                kp = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv));
            } else {
                // if here, the key it's protected by password
                LogAppl.getInstance().emit(NodeMessage.JEMC199W);
                kp = converter.getKeyPair((PEMKeyPair) object);
            }
            return kp.getPrivate();
        } catch (FileNotFoundException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (PEMException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (IOException e) {
            throw new KeyException(e.getMessage(), e);
        }
    }

    /**
     * Encrypt a text using a key
     * @param text to encrypt in byte
     * @param key to use to encrypt text
     * @return the encrypted text as an array of byte
     * @throws KeyException if any error occurs during the process
     */
    public static byte[] encrypt(byte[] text, Key key) throws KeyException {
        try {
            // using security package
            Cipher cipher = Cipher.getInstance(key.getAlgorithm());
            // init the cipher
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // encrypt the text 
            byte[] plaintext = text;
            return cipher.doFinal(plaintext);
        } catch (InvalidKeyException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (NoSuchAlgorithmException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (NoSuchPaddingException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (IllegalBlockSizeException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (BadPaddingException e) {
            throw new KeyException(e.getMessage(), e);
        }
    }

    /**
     * Decrypt an encrypted text using a key
     * @param encryptText the text to decrypt in byte
     * @param key used to decrypt text
     * @return the decrypted text as an array of byte
     * @throws KeyException if any error occurs during the process
     */
    public static byte[] decrypt(byte[] encryptText, Key key) throws KeyException {
        try {
            // using security package
            Cipher cipher = Cipher.getInstance(key.getAlgorithm());
            // init the cipher
            cipher.init(Cipher.DECRYPT_MODE, key);
            // encrypt the text 
            return cipher.doFinal(encryptText);
        } catch (InvalidKeyException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (NoSuchAlgorithmException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (NoSuchPaddingException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (IllegalBlockSizeException e) {
            throw new KeyException(e.getMessage(), e);
        } catch (BadPaddingException e) {
            throw new KeyException(e.getMessage(), e);
        }
    }

    /**
     * Generate a simmetric key, with 168 bit 
     * @return a secret TripleDES encryption/decryption key with 168 bit
     * @throws NoSuchAlgorithmException if any error occurs
     */
    public static SecretKey generateSymmetricKey() throws NoSuchAlgorithmException {
        // Get a key generator for Triple DES (a.k.a DESede)
        KeyGenerator keygen = KeyGenerator.getInstance(DESEDE_ALGORITHM);
        // set key size
        keygen.init(168);
        // Use it to generate a key
        return keygen.generateKey();
    }
}