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 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);
  }
  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);
    }
  }
  /**
   * 입력받은 스트림을 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();
    }
  }