egovframework.com.ext.jfile.security.service.CipherServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for egovframework.com.ext.jfile.security.service.CipherServiceImpl.java

Source

/*
 * eGovFrame JFile
 * Copyright The eGovFrame Open Community (http://open.egovframe.go.kr)).
 *
 * 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.
 * 
 * @author  (?  ?)
 */
package egovframework.com.ext.jfile.security.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

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

import egovframework.com.ext.jfile.security.JCrypto;

/**
 *  ?
 * @author 
 * @since 2010.10.17
 * @version 1.0
 * @see
 *
 * <pre>
 * << ?(Modification Information) >>
 *   
 *   ?        ?       
 *  -------       --------    ---------------------------
 *   2010.10.17           ?
 *   2013.12.19   ?   ?  ? (  ? sun.misc   )
 *
 * </pre>
 */
public class CipherServiceImpl implements CipherService {

    /**
     *  ?
     */
    private JCrypto jcrypto;

    /**
     *  ? ..
     * @param jcrypto  ?
     */
    public void setJcrypto(JCrypto jcrypto) {
        this.jcrypto = jcrypto;
    }

    /**
     *  ? .
     * @return Cipher  ?.
     * @throws NoSuchAlgorithmException ? ?  ?  .
     * @throws NoSuchPaddingException   ?  ?  .
     */
    private Cipher getCipherInstance() throws NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance(this.jcrypto.getAlgorithm());
        return cipher;
    }

    /**
     *   ?.
     * @param keyAlgorithm  .
     * @param algorithm .
     * @param keyData  ??.
     * @return Key  .
     * @throws NoSuchAlgorithmException   ?  ?  .
     * @throws InvalidKeyException  ? key ?  
     * @throws InvalidKeySpecException  ? keySpec ?  
     */
    private static Key generateKey(String keyAlgorithm, String algorithm, byte[] keyData)
            throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
        if (keyAlgorithm == null || "".equals(keyAlgorithm))
            throw new NoSuchAlgorithmException("algorithm is nessary");
        String upper = keyAlgorithm.toUpperCase();
        if ("DES".equals(upper)) {
            KeySpec keySpec = new DESKeySpec(keyData);
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(keyAlgorithm);

            SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
            return secretKey;

        } else if (upper.indexOf("DESEDE") > -1 || upper.indexOf("TRIPLEDES") > -1) {
            KeySpec keySpec = new DESedeKeySpec(keyData);

            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(keyAlgorithm);
            SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
            return secretKey;
        } else {
            SecretKeySpec keySpec = new SecretKeySpec(keyData, keyAlgorithm);
            return keySpec;
        }
    }

    public byte[] encrypt(byte[] data) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException,
            IOException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException,
            InvalidAlgorithmParameterException {
        Cipher cipher = getCipherInstance();

        if (JCryptoHelper.isNecessaryIvBytes(this.jcrypto.getAlgorithm())) {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(JCryptoHelper.DEFAULT_IV_BYTES);
            cipher.init(Cipher.ENCRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()), ivParameterSpec);
        } else {
            cipher.init(Cipher.ENCRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()));
        }
        if (jcrypto.isApplyBase64()) {
            //sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
            //return encoder.encode(cipher.doFinal(data)).getBytes();
            return Base64.encodeBase64(cipher.doFinal(data));

        } else {
            return cipher.doFinal(data);
        }
    }

    public byte[] decrypt(byte[] data)
            throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
            IllegalBlockSizeException, BadPaddingException, IOException, InvalidAlgorithmParameterException {
        Cipher cipher = getCipherInstance();
        if (JCryptoHelper.isNecessaryIvBytes(this.jcrypto.getAlgorithm())) {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(JCryptoHelper.DEFAULT_IV_BYTES);
            cipher.init(Cipher.DECRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()), ivParameterSpec);
        } else {
            cipher.init(Cipher.DECRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()));
        }

        byte[] bData = null;
        if (jcrypto.isApplyBase64()) {

            //byte[] temp = new sun.misc.BASE64Decoder().decodeBuffer(new String(   data));
            byte[] temp = Base64.decodeBase64(data);
            bData = temp;
        } else {
            bData = data;
        }

        return cipher.doFinal(bData);

    }

    public void decrypt(InputStream in, OutputStream out) throws NoSuchAlgorithmException, InvalidKeyException,
            IOException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException,
            InvalidKeySpecException, InvalidAlgorithmParameterException {
        decrypt(in, out, true);
    }

    public void decryptForZipFile(InputStream in, OutputStream out) throws NoSuchAlgorithmException,
            InvalidKeyException, IOException, IllegalBlockSizeException, NoSuchPaddingException,
            BadPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException {
        decrypt(in, out, false);
    }

    public void encrypt(InputStream in, OutputStream out)
            throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IOException,
            BadPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(jcrypto.getAlgorithm());
        if (JCryptoHelper.isNecessaryIvBytes(this.jcrypto.getAlgorithm())) {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(JCryptoHelper.DEFAULT_IV_BYTES);
            cipher.init(Cipher.ENCRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()), ivParameterSpec);
        } else {
            cipher.init(Cipher.ENCRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()));
        }

        CipherOutputStream cos = new CipherOutputStream(out, cipher);

        byte[] buffer = new byte[2048];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            cos.write(buffer, 0, bytesRead);
            cos.flush();
        }
        cos.close();

        java.util.Arrays.fill(buffer, (byte) 0);
    }

    /**
     *  ? ? close      . 
     * @param in  
     * @param out  
     * @param isStreamClose close 
     * @throws NoSuchAlgorithmException  ? ?  ?  
     * @throws InvalidKeyException ?  ? key ?  
     * @throws IOException /  
     * @throws IllegalBlockSizeException ?  ? ? ?  
     * @throws NoSuchPaddingException   ?  ?  
     * @throws BadPaddingException ?  ? 
     * @throws InvalidKeySpecException ?  ? keySpec ?  
     * @throws InvalidAlgorithmParameterException  ?  ? ? 
     */
    private void decrypt(InputStream in, OutputStream out, boolean isStreamClose) throws NoSuchAlgorithmException,
            InvalidKeyException, IOException, IllegalBlockSizeException, NoSuchPaddingException,
            BadPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(jcrypto.getAlgorithm());
        if (JCryptoHelper.isNecessaryIvBytes(this.jcrypto.getAlgorithm())) {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(JCryptoHelper.DEFAULT_IV_BYTES);
            cipher.init(Cipher.DECRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()), ivParameterSpec);
        } else {
            cipher.init(Cipher.DECRYPT_MODE, generateKey(JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
                    this.jcrypto.getAlgorithm(), this.jcrypto.getKeyBytes()));
        }

        byte[] buffer = new byte[2048];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(cipher.update(buffer, 0, bytesRead));
        }

        out.write(cipher.doFinal());
        out.flush();
        if (isStreamClose) {
            in.close();
            out.close();
        }
    }

    /**
     *  Helper ?
     *
     */
    static class JCryptoHelper {

        /** ?  ivBytes   . */
        public static byte[] DEFAULT_IV_BYTES = { (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 7,
                (byte) 1, (byte) 2 };

        /** ?  ?  ?  ? .*/
        public static String getKeyAlgorithm(String algorithm) {
            return algorithm.split("\\/")[0];
        }

        /** ??  ivBytes  . */
        public static boolean isNecessaryIvBytes(String algorithm) {
            String[] algorithmArr = algorithm.split("\\/");

            if (algorithmArr.length == 1) {
                return false;
            } else if (algorithmArr.length == 2 || algorithmArr.length == 3) {
                if ("CBC".equalsIgnoreCase(algorithmArr[1]) || "OFB".equalsIgnoreCase(algorithmArr[1])
                        || "CFB".equalsIgnoreCase(algorithmArr[1])) {
                    return true;
                } else {
                    return false;
                }
            }
            return false;
        }
    }
}