Java tutorial
/** * Copyright 2005-2015 titilink * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL * 1.0 (the "Licenses"). You can select the license that you prefer but you may * not use this file except in compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the LGPL 3.0 license at * http://www.opensource.org/licenses/lgpl-3.0 * * You can obtain a copy of the LGPL 2.1 license at * http://www.opensource.org/licenses/lgpl-2.1 * * You can obtain a copy of the CDDL 1.0 license at * http://www.opensource.org/licenses/cddl1 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * https://github.com/titilink/titilink-framework * * titilink is a registered trademark of titilink.inc */ package com.titilink.camel.rest.util; import com.titilink.common.app.AppProperties; import com.titilink.common.log.AppLogger; import org.apache.commons.codec.binary.Base64; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; /** * * <p> * @author by kam * @date 2015/05/01 * @since v1.0.0 */ public final class PasswordUtils { private static final AppLogger LOGGER = AppLogger.getInstance(PasswordUtils.class); /** * ??16 */ private static final int DECIMAL_16 = 16; /** * ,?50000 */ private static final int ITERATION_COUNT = 50000; /** * AES */ private static final int AES_KEY_LEN = 128; /** * key_pass */ private static final String DEFAULT_KEY_PASS = "OMM@123"; /** * salt */ private static final String DEFAULT_SALT = "y5x6G+jW9w=="; /** * IV?? */ private static final String DEFAULT_IV = "U56ClHWVWbdw5PljZtGNpQ=="; /** * string?? */ public static final String ENCODING_UTF8 = "UTF-8"; /** * AES */ public static final String ENCODER_AES = "AES"; /** * SHA-256 */ public static final String ENCODER_SHA256 = "SHA-256"; /** * AES */ public static final String ENCODER_MUTIL = "AES/CBC/PKCS5Padding"; /** * SecureRandom */ public static final String ALGORITHM_SHA1PRNG = "SHA1PRNG"; /** * IV??? */ private static final int DECIMAL_8 = 8; /** * */ private static Key skeySpec = null; /** * ?? */ private static IvParameterSpec ivpspec = null; /** * checkstyle: ??? */ private PasswordUtils() { // NOP } /** * ?????? * * @param content * @param ivparam ?? */ private static void initParams(String content, byte[] ivparam) { checkParams(content, ivparam); if (null == skeySpec) { loadKey(); } ivpspec = new IvParameterSpec(ivparam); } /** * Rabiitsalt?AES????SHA256??. * * @param Rabiit ?? * @param salt ? * @return */ public synchronized static Key generateKey(char[] Rabiit, byte[] salt) { SecretKeyFactory factory; SecretKey tmpkey = null; SecretKey secret = null; try { factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); //AES128??AES128 int aeskeylen = AppProperties.getAsInt("AES_KEY_LEN", AES_KEY_LEN); KeySpec keyspec = new PBEKeySpec(Rabiit, salt, ITERATION_COUNT, aeskeylen); tmpkey = factory.generateSecret(keyspec); //AES?? secret = new SecretKeySpec(tmpkey.getEncoded(), ENCODER_AES); } catch (NoSuchAlgorithmException e) { LOGGER.error("generateKey error, no such method exception."); } // "PBKDF2WithHmacSHA256" JDK8?? catch (InvalidKeySpecException e) { LOGGER.error("generateKey error, invalid key exception."); } return secret; } /** * ??? * * @param secRetKeyByte * @param algorithm ?? * @return Key */ private static Key generateKey(byte[] secRetKeyByte, String algorithm) { return new SecretKeySpec(secRetKeyByte, algorithm); } /** * */ private synchronized static void loadKey() { try { if (null != skeySpec) { return; } String keyPass = AppProperties.get("KEY_PASS", DEFAULT_KEY_PASS); byte[] salt = Base64.decodeBase64(DEFAULT_SALT); skeySpec = generateKey(keyPass.toCharArray(), salt); } catch (Throwable t) { LOGGER.error("loadKey error."); } } /** * AES * * @param plainText * @param secRetKeyByte * @return String */ public synchronized static String aesEncrypt(String plainText, byte[] secRetKeyByte) { checkParams(plainText, secRetKeyByte); Key key = generateKey(secRetKeyByte, ENCODER_AES); String encryptResult = null; try { // ? Cipher cipher = Cipher.getInstance(ENCODER_AES); byte[] byteContent = plainText.getBytes(ENCODING_UTF8); // ? cipher.init(Cipher.ENCRYPT_MODE, key); byte[] result = cipher.doFinal(byteContent); encryptResult = Base64.encodeBase64String(result); } catch (NoSuchAlgorithmException e) { LOGGER.error("aesEncrypt error, no such algorithm exception"); } catch (NoSuchPaddingException e) { LOGGER.error("aesEncrypt error, no such padding exception"); } catch (UnsupportedEncodingException e) { LOGGER.error("aesEncrypt error, unsupported encoding exception"); } catch (InvalidKeyException e) { LOGGER.error("aesEncrypt error, invalid key exception"); } catch (IllegalBlockSizeException e) { LOGGER.error("aesEncrypt error, illegal block size exception"); } catch (BadPaddingException e) { LOGGER.error("aesEncrypt error, bad padding exception"); } return encryptResult; } /** * ?AES * * @param ciphertext * @param secRetKeyByte * @return String */ public synchronized static String aesDecrpt(String ciphertext, byte[] secRetKeyByte) { //? checkParams(ciphertext, secRetKeyByte); String decryptResult = null; Key key = generateKey(secRetKeyByte, ENCODER_AES); try { // ? Cipher cipher = Cipher.getInstance(ENCODER_AES); // ? cipher.init(Cipher.DECRYPT_MODE, key); byte[] result = cipher.doFinal(Base64.decodeBase64(ciphertext)); decryptResult = new String(result, ENCODING_UTF8); } catch (NoSuchAlgorithmException e) { LOGGER.error("aesDecrpt error, no such algorithm exception"); } catch (NoSuchPaddingException e) { LOGGER.error("aesDecrpt error, no such padding exception"); } catch (InvalidKeyException e) { LOGGER.error("aesDecrpt error, invalid key exception"); } catch (IllegalBlockSizeException e) { LOGGER.error("aesDecrpt error, illegal block size exception"); } catch (BadPaddingException e) { LOGGER.error("aesDecrpt error, bad padding exception"); } catch (IOException e) { LOGGER.error("aesDecrpt error, io exception"); } return decryptResult; } /** * ?????? * * @param content * @return */ public synchronized static String encryptByAes(String content) { byte[] defaultiv = Base64.decodeBase64(DEFAULT_IV); return encryptByAes(content, defaultiv); } /** * AES * * @param content ? * @param ivparam ?? * @return */ public synchronized static String encryptByAes(String content, byte[] ivparam) { initParams(content, ivparam); return encryptByAes(content, skeySpec, ivpspec); } /** * AES * * @param content * @param key * @param ivp ?? * @return String */ private static String encryptByAes(String content, Key key, IvParameterSpec ivp) { String encryptResult = ""; if (null == content) { return encryptResult; } try { // ? Cipher cipher = Cipher.getInstance(ENCODER_MUTIL); byte[] byteContent = content.getBytes(ENCODING_UTF8); // ? cipher.init(Cipher.ENCRYPT_MODE, key, ivp); byte[] result = cipher.doFinal(byteContent); encryptResult = Base64.encodeBase64String(result); } catch (NoSuchAlgorithmException e) { LOGGER.error("encryptByAes error, no such algorithm exception"); } catch (NoSuchPaddingException e) { LOGGER.error("encryptByAes error, no such padding exception"); } catch (UnsupportedEncodingException e) { LOGGER.error("encryptByAes error, unsupported encoding exception"); } catch (InvalidKeyException e) { LOGGER.error("encryptByAes error, invalid key exception"); } catch (IllegalBlockSizeException e) { LOGGER.error("encryptByAes error, illegal block size exception"); } catch (BadPaddingException e) { LOGGER.error("encryptByAes error, bad padding exception"); } catch (InvalidAlgorithmParameterException e) { LOGGER.error("encryptByAes error, invalid algorithm parameter exception"); } return encryptResult; } /** * ?????? * * @param content * @return */ public synchronized static String decryptByAes(String content) { byte[] defaultiv = Base64.decodeBase64(DEFAULT_IV); return decryptByAes(content, defaultiv); } /** * * * @param content * @param ivparam ?? * @return String * */ public synchronized static String decryptByAes(String content, byte[] ivparam) { initParams(content, ivparam); return decryptByAes(content, skeySpec, ivpspec); } /** * AES * * @param content * @param key * @param ivp ?? * @return */ public synchronized static String decryptByAes(String content, Key key, IvParameterSpec ivp) { // String decryptResult = ""; if (null == content) { return decryptResult; } try { // ? Cipher cipher = Cipher.getInstance(ENCODER_MUTIL); // ? cipher.init(Cipher.DECRYPT_MODE, key, ivp); byte[] result = cipher.doFinal(Base64.decodeBase64(content)); decryptResult = new String(result, ENCODING_UTF8); } catch (NoSuchAlgorithmException e) { LOGGER.error("decryptByAes error, no such algorithm exception"); } catch (NoSuchPaddingException e) { LOGGER.error("decryptByAes error, no such padding exception"); } catch (UnsupportedEncodingException e) { LOGGER.error("decryptByAes error, unsupported encoding exception"); } catch (InvalidKeyException e) { LOGGER.error("decryptByAes error, invalid key exception"); } catch (IllegalBlockSizeException e) { LOGGER.error("decryptByAes error, illegal block size exception"); } catch (BadPaddingException e) { LOGGER.error("decryptByAes error, bad padding exception"); } catch (InvalidAlgorithmParameterException e) { LOGGER.error("decryptByAes error, invalid algorithm parameter exception"); } return decryptResult; } /** * SHA256 * * @param content * @return */ public synchronized static String encryptBySHA256(String content) { // String encryptResultStr = ""; if (null == content) { return encryptResultStr; } try { // ?MessageDigest,?(SHA-1) MessageDigest msgDigest = MessageDigest.getInstance(ENCODER_SHA256); // getBytes( )? msgDigest.update(content.getBytes(ENCODING_UTF8)); // MessageDigestdigest( )? byte[] digesta = msgDigest.digest(); encryptResultStr = OtherUtil.parseByte2HexStr(digesta); } catch (NoSuchAlgorithmException e) { LOGGER.error("encryptBySHA256 error, no such algorithm exception"); } catch (UnsupportedEncodingException e) { LOGGER.error("encryptBySHA256 error, unsupported encoding exception"); } return encryptResultStr; } /** * SecureRandom????? * * @return ? */ public synchronized static byte[] generateSecRamdom() { try { SecureRandom sr = SecureRandom.getInstance(ALGORITHM_SHA1PRNG); byte[] bytes = new byte[DECIMAL_16]; sr.nextBytes(bytes); return bytes; } catch (NoSuchAlgorithmException e) { LOGGER.error("generateSecRamdom error, no such algorithm exception"); } return null; } /** * ??? * * @param content * @param ivparam */ private static void checkParams(String content, byte[] ivparam) { if ((null == content) || (content.isEmpty())) { throw new RuntimeException("the content to encrpt is null or empty"); } if ((null == ivparam) || (ivparam.length < DECIMAL_8)) { throw new RuntimeException("byte[] is null or less than eight bytes"); } } /** * AES * * @param plainText * @param secRetKeyByte * @return String */ public synchronized static String aesEncryptSpec(String plainText, byte[] secRetKeyByte) { checkParams(plainText, secRetKeyByte); Key key = generateKey(secRetKeyByte, ENCODER_AES); String encryptResult = null; try { // ? Cipher cipher = Cipher.getInstance(ENCODER_AES); byte[] byteContent = plainText.getBytes(ENCODING_UTF8); // ? cipher.init(Cipher.ENCRYPT_MODE, key); byte[] result = cipher.doFinal(byteContent); encryptResult = OtherUtil.parseByte2HexStr(result); } catch (NoSuchAlgorithmException e) { LOGGER.error("aesEncryptSpec error, no such algorithm exception"); } catch (NoSuchPaddingException e) { LOGGER.error("aesEncryptSpec error, no such padding exception"); } catch (UnsupportedEncodingException e) { LOGGER.error("aesEncryptSpec error, unsupported encoding exception"); } catch (InvalidKeyException e) { LOGGER.error("aesEncryptSpec error, invalid key exception"); } catch (IllegalBlockSizeException e) { LOGGER.error("aesEncryptSpec error, illegal block size exception"); } catch (BadPaddingException e) { LOGGER.error("aesEncryptSpec error, bad padding exception"); } return encryptResult; } /** * ?AES * * @param ciphertext * @param secRetKeyByte * @return String */ public synchronized static String aesDecrptSpec(String ciphertext, byte[] secRetKeyByte) { //? checkParams(ciphertext, secRetKeyByte); String decryptResult = null; Key key = generateKey(secRetKeyByte, ENCODER_AES); try { // ? Cipher cipher = Cipher.getInstance(ENCODER_AES); // ? cipher.init(Cipher.DECRYPT_MODE, key); byte[] result = cipher.doFinal(OtherUtil.parseHexStr2Byte(ciphertext)); decryptResult = new String(result); } catch (NoSuchAlgorithmException e) { LOGGER.error("aesDecrptSpec error, no such algorithm exception"); } catch (NoSuchPaddingException e) { LOGGER.error("aesDecrptSpec error, no such padding exception"); } catch (InvalidKeyException e) { LOGGER.error("aesDecrptSpec error, invalid key exception"); } catch (IllegalBlockSizeException e) { LOGGER.error("aesDecrptSpec error, illegal block size exception"); } catch (BadPaddingException e) { LOGGER.error("aesDecrptSpec error, bad padding exception"); } return decryptResult; } }