Package org.jamwiki.utils

Source Code of org.jamwiki.utils.Encryption

/**
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the latest version of the GNU Lesser General
* Public License as published by the Free Software Foundation;
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program (LICENSE.txt); if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package org.jamwiki.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.jamwiki.Environment;

/**
* Provide capability for encrypting and decrypting values. Inspired by an
* example from http://www.devx.com/assets/sourcecode/10387.zip.
*/
public class Encryption {

  private static final WikiLogger logger = WikiLogger
      .getLogger(Encryption.class.getName());
  public static final String DES_ALGORITHM = "DES";
  public static final String ENCRYPTION_KEY = "JAMWiki Key 12345";

  /**
   * Hide the constructor by making it private.
   */
  private Encryption() {
  }

  /**
   * Encrypt a String value using the DES encryption algorithm.
   *
   * @param unencryptedBytes
   *          The unencrypted String value that is to be encrypted.
   * @return An encrypted version of the String that was passed to this method.
   */
  private static String encrypt64(byte[] unencryptedBytes)
      throws GeneralSecurityException, UnsupportedEncodingException {
    if (unencryptedBytes == null || unencryptedBytes.length == 0) {
      throw new IllegalArgumentException(
          "Cannot encrypt a null or empty byte array");
    }
    SecretKey key = createKey();
    Cipher cipher = Cipher.getInstance(key.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] encryptedBytes = Base64.encodeBase64(cipher
        .doFinal(unencryptedBytes));
    return bytes2String(encryptedBytes);
  }

  /**
   *
   */
  public static String encrypt(String unencryptedString) {
    if (StringUtils.isBlank(unencryptedString)) {
      throw new IllegalArgumentException(
          "Cannot encrypt a null or empty string");
    }
    MessageDigest md = null;
    String encryptionAlgorithm = Environment
        .getValue(Environment.PROP_ENCRYPTION_ALGORITHM);
    try {
      md = MessageDigest.getInstance(encryptionAlgorithm);
    } catch (NoSuchAlgorithmException e) {
      logger.warning("JDK does not support the " + encryptionAlgorithm
          + " encryption algorithm.  Weaker encryption will be attempted.");
    }
    if (md == null) {
      // fallback to weaker encryption algorithm if nothing better is available
      try {
        md = MessageDigest.getInstance("SHA-1");
      } catch (NoSuchAlgorithmException e) {
        throw new UnsupportedOperationException(
            "JDK does not support the SHA-1 or SHA-512 encryption algorithms");
      }
      // save the algorithm so that if the user upgrades the JDK they can
      // still use passwords encrypted with the weaker algorithm
      Environment.setValue(Environment.PROP_ENCRYPTION_ALGORITHM, "SHA-1");
      // trY {
      // ENVIRONMENT.SAVEPROPERTIES();
      // } CATCH (IOEXCEPTION E) {
      // LOGGER.INFO("FAILURE WHILE SAVING ENCRYPTION ALGORITHM PROPERTY", E);
      // }
    }
    try {
      md.update(unencryptedString.getBytes("UTF-8"));
      byte raw[] = md.digest();
      return encrypt64(raw);
    } catch (GeneralSecurityException e) {
      logger.severe("Encryption failure", e);
      throw new IllegalStateException("Failure while encrypting value");
    } catch (UnsupportedEncodingException e) {
      // this should never happen
      throw new IllegalStateException("Unsupporting encoding UTF-8");
    }
  }

  /**
   * Unencrypt a String value using the DES encryption algorithm.
   *
   * @param encryptedString
   *          The encrypted String value that is to be unencrypted.
   * @return An unencrypted version of the String that was passed to this
   *         method.
   */
  private static String decrypt64(String encryptedString)
      throws GeneralSecurityException, UnsupportedEncodingException {
    if (StringUtils.isBlank(encryptedString)) {
      return encryptedString;
    }
    SecretKey key = createKey();
    Cipher cipher = Cipher.getInstance(key.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, key);
    byte[] encryptedBytes = encryptedString.getBytes("UTF8");
    byte[] unencryptedBytes = cipher.doFinal(Base64
        .decodeBase64(encryptedBytes));
    return bytes2String(unencryptedBytes);
  }

  /**
   * Convert a byte array to a String value.
   *
   * @param bytes
   *          The byte array that is to be converted.
   * @return A String value created from the byte array that was passed to this
   *         method.
   */
  private static String bytes2String(byte[] bytes) {
    StringBuilder buffer = new StringBuilder();
    for (int i = 0; i < bytes.length; i++) {
      buffer.append((char) bytes[i]);
    }
    return buffer.toString();
  }

  /**
   * Create the encryption key value.
   *
   * @return An encryption key value implementing the DES encryption algorithm.
   */
  private static SecretKey createKey() throws GeneralSecurityException,
      UnsupportedEncodingException {
    byte[] bytes = ENCRYPTION_KEY.getBytes("UTF8");
    DESKeySpec spec = new DESKeySpec(bytes);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
    return keyFactory.generateSecret(spec);
  }

  /**
   * If a property value is encrypted, return the unencrypted value. Note that
   * if this method finds an un-encrypted value it will automatically encrypt it
   * and re-save it to the property file.
   *
   * @param name
   *          The name of the encrypted property being retrieved.
   * @return The unencrypted value of the property.
   */
  public static String getEncryptedProperty(String name, Properties props) {
    try {
      if (props != null) {
        return Encryption.decrypt64(props.getProperty(name));
      }
      return Encryption.decrypt64(Environment.getValue(name));
    } catch (GeneralSecurityException e) {
      String value = Environment.getValue(name);
      if (props != null || StringUtils.isBlank(value)) {
        logger.severe("Encryption failure or no value available for property: "
            + name, e);
        throw new IllegalStateException(
            "Failure while retrieving encrypted property: " + name);
      }
      // the property might have been unencrypted in the property file, so
      // encrypt, save, and return the value
      logger
          .warning("Found unencrypted property file value: "
              + name
              + ".  Assuming that this value manually un-encrypted in the property file so re-encrypting and re-saving.");
      Encryption.setEncryptedProperty(name, value, null);
      // try {
      // Environment.saveProperties();
      // } catch (IOException ex) {
      // logger.severe("Failure while saving properties", ex);
      // throw new IllegalStateException("Failure while saving properties");
      // }
      return value;
    } catch (UnsupportedEncodingException e) {
      throw new IllegalStateException("Unsupporting encoding UTF-8");
    }
  }

  /**
   * Encrypt and set a property value.
   *
   * @param name
   *          The name of the encrypted property being retrieved.
   * @param value
   *          The unenencrypted value of the property.
   * @param props
   *          The property object in which the property is being set.
   */
  public static void setEncryptedProperty(String name, String value,
      Properties props) {
    String encrypted = "";
    if (!StringUtils.isBlank(value)) {
      byte[] unencryptedBytes = null;
      try {
        unencryptedBytes = value.getBytes("UTF8");
        encrypted = Encryption.encrypt64(unencryptedBytes);
      } catch (GeneralSecurityException e) {
        logger.severe("Encryption failure", e);
        throw new IllegalStateException("Failure while encrypting value");
      } catch (UnsupportedEncodingException e) {
        // this should never happen
        throw new IllegalStateException("Unsupporting encoding UTF-8");
      }
    }
    if (props == null) {
      Environment.setValue(name, encrypted);
    } else {
      props.setProperty(name, encrypted);
    }
  }
}
TOP

Related Classes of org.jamwiki.utils.Encryption

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.