org.cogroo.addon.util.SecurityUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.cogroo.addon.util.SecurityUtil.java

Source

/**
 * Copyright (C) 2012 cogroo <cogroo@cogroo.org>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cogroo.addon.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

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

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.cogroo.addon.LoggerImpl;

public class SecurityUtil {

    private static final String UTF8 = "UTF-8";
    protected static Logger LOG = LoggerImpl.getLogger(SecurityUtil.class.getCanonicalName());

    /**
     * Encrypt data using an key encrypted with a private key.
     * @param privateKey the private key to decrypt the secret key
     * @param encryptedSecretKey a encrypted secret key
     * @param data the data to encrypt
     * @return the encrypted data
     * @throws InvalidKeyException one of the keys is invalid
     */
    public byte[] encrypt(PrivateKey privateKey, byte[] encryptedSecretKey, String data)
            throws InvalidKeyException {
        byte[] encryptedData = null;
        try {
            byte[] chave = privateKey.getEncoded();
            // Decrypt secret symmetric key with private key
            Cipher rsacf = Cipher.getInstance("RSA");
            rsacf.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] secretKey = rsacf.doFinal(encryptedSecretKey);

            encryptedData = encrypt(secretKey, data);
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Exception encrypting data", e);
        }

        return encryptedData;
    }

    private byte[] encrypt(byte[] secretKey, String data) throws InvalidKeyException {
        byte[] encryptedData = null;
        try {
            // Encrypt data using the secret key
            Cipher aescf = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivspec = new IvParameterSpec(new byte[16]);
            aescf.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secretKey, "AES"), ivspec);
            encryptedData = aescf.doFinal(data.getBytes(UTF8));
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Exception encrypting data", e);
        }
        return encryptedData;
    }

    private byte[] decryptSecretKey(PrivateKey privatekey, byte[] encryptedSecretKey) {
        byte[] result = null;
        try {
            Cipher rsacf = Cipher.getInstance("RSA");
            rsacf.init(Cipher.DECRYPT_MODE, privatekey);
            result = rsacf.doFinal(encryptedSecretKey);
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Error", e);
        }
        return result;
    }

    public byte[] decrypt(PrivateKey privateKey, byte[] encryptedSecretKey, byte[] encryptedText) {
        byte[] text = null;
        try {
            byte[] secretKey = decryptSecretKey(privateKey, encryptedSecretKey);
            text = decrypt(secretKey, encryptedText);
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Should not happen", e);
        }

        return text;
    }

    private byte[] decrypt(byte[] secretKey, byte[] encryptedText) {
        byte[] text = null;
        try {
            Cipher aescf = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivspec = new IvParameterSpec(new byte[16]);
            aescf.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey, "AES"), ivspec);
            text = aescf.doFinal(encryptedText);

        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Should not happen", e);
        }

        return text;
    }

    private static final int RSAKEYSIZE = 1024;

    public KeyPair genKeyPair() {
        KeyPair kpr = null;
        try {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
            kpg.initialize(new RSAKeyGenParameterSpec(RSAKEYSIZE, RSAKeyGenParameterSpec.F4));
            kpr = kpg.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            LOG.log(Level.SEVERE, "Error generating key pair", e);
        } catch (InvalidAlgorithmParameterException e) {
            LOG.log(Level.SEVERE, "Error generating key pair", e);
        }
        return kpr;
    }

    public String encode(byte[] key) {
        return StringUtils.newStringUtf8(Base64.encodeBase64(key, false));
    }

    public static String encodeURLSafe(String data) {
        String ret = null;
        try {
            ret = URLEncoder.encode(data, UTF8);
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Should not happen", e);
        }
        return ret;
    }

    public String encodeURLSafe(byte[] key) {
        String encKey = null;
        try {
            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("encode 01: key " + Arrays.toString(key));
            }
            String value = encode(key);
            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("encode 02 value: " + value);
            }
            encKey = URLEncoder.encode(value, UTF8);
        } catch (UnsupportedEncodingException e) {
            LOG.log(Level.SEVERE, "Should not happen", e);
        }
        return encKey;
    }

    public byte[] decodeURLSafe(String encoded) {
        byte[] bytes = null;
        try {
            bytes = Base64.decodeBase64(URLDecoder.decode(encoded, UTF8).getBytes(UTF8));
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Error decoding string: " + encoded, e);
        }
        return bytes;
    }

    /**
     * Encrypt a string using SHA
     * @param plaintext the original text
     * @return resultant hash
     */
    public synchronized String encrypt(String plaintext) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA");
            md.update(plaintext.getBytes(UTF8));
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "Should not happen!", e);
        }
        byte raw[] = md.digest();

        return encode(raw);
    }
}