Java tutorial
/* * Copyright 2013-2023 Peng Li <madding.lip@gmail.com> * Licensed under the AQNote License, Version 1.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.aqnote.com/licenses/LICENSE-1.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 com.aqnote.shared.encrypt.symmetric; import static com.aqnote.shared.encrypt.cert.bc.constant.BCConstant.JCE_PROVIDER; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import com.aqnote.shared.encrypt.ProviderUtil; /** * Blowfish.java?? * * <pre> * Blowfish? Bruce Schneier ? * ? 32 ? 448 ? 8 ???? * (Blowfish/CBC/PKCS5Padding)Blowfish?CBC?PKCS5Padding??8 ? * </pre> * * @author madding.lip May 8, 2012 2:08:19 PM */ public class Blowfish { private static final String CIPHER_NAME = "Blowfish/CBC/PKCS5Padding"; private static final String PROVIDER_NAME = JCE_PROVIDER; private static final String DEFAULT_KEY = "www.aqnote.com"; private static final String DEFAULT_CHARSET = "UTF-8"; private static Cipher encryptCipher = null; private static Cipher decryptCipher = null; private static Key key = null; private static AlgorithmParameterSpec iv = null; static { generateCipher(DEFAULT_KEY); } private static void generateCipher(String rawKey) { ProviderUtil.addBCProvider(); encryptCipher = instanceCipher(CIPHER_NAME, PROVIDER_NAME); decryptCipher = instanceCipher(CIPHER_NAME, PROVIDER_NAME); key = generateKey(rawKey); iv = generateIV(); initCipher(encryptCipher, Cipher.ENCRYPT_MODE, key, iv); initCipher(decryptCipher, Cipher.DECRYPT_MODE, key, iv); } /** * ? * * @return Key */ private static Key generateKey(String keyStr) { byte[] keyBytes = null; try { if (keyStr == null) { keyBytes = DEFAULT_KEY.getBytes(DEFAULT_CHARSET); } else { keyBytes = keyStr.getBytes(DEFAULT_CHARSET); } } catch (UnsupportedEncodingException e) { } return new SecretKeySpec(keyBytes, "Blowfish"); } /** * ?? * * @return AlgorithmParameterSpec */ private static AlgorithmParameterSpec generateIV() { byte[] algorithmBytes = new byte[] { 20, -114, -36, -120, -36, -37, 48, 92 }; return new IvParameterSpec(algorithmBytes); } /** * * * @param name * cipher name * @param provider * provider name * @return Cipher */ private static Cipher instanceCipher(String name, String provider) { Cipher cipher = null; try { cipher = Cipher.getInstance(name, provider); } catch (NoSuchAlgorithmException e) { } catch (NoSuchProviderException e) { } catch (NoSuchPaddingException e) { } return cipher; } /** * ? * * @param cipher * Cipher * @param opmode * operation mode (ENCRYPT_MODE?DECRYPT_MODE?WRAP_MODE * UNWRAP_MODE) * @param key * Key * @param iv * AlgorithmParameterSpec */ private static void initCipher(Cipher cipher, int opmode, Key key, AlgorithmParameterSpec iv) { try { cipher.init(opmode, key, iv); } catch (InvalidKeyException e) { } catch (InvalidAlgorithmParameterException e) { } } /** * ?CipherdoFinal?reset ??? * * @param b * ? * @return ? * @throws IllegalBlockSizeException * @throws BadPaddingException */ public synchronized static byte[] encrypt(byte[] b) throws IllegalBlockSizeException, BadPaddingException { byte[] buffer = null; initCipher(encryptCipher, Cipher.ENCRYPT_MODE, key, iv); buffer = encryptCipher.doFinal(b); return buffer; } /** * ?CipherdoFinal?reset ??? * * @param b * ? * @return ? * @throws IllegalBlockSizeException * @throws BadPaddingException */ public synchronized static byte[] decrypt(byte[] b) throws IllegalBlockSizeException, BadPaddingException { byte[] buffer = null; initCipher(decryptCipher, Cipher.DECRYPT_MODE, key, iv); buffer = decryptCipher.doFinal(b); return buffer; } /** * @param str * ? * @return String ? */ public static String encrypt(String str) { String result = null; if (!StringUtils.isEmpty(str)) { try { byte[] src = str.getBytes(DEFAULT_CHARSET); byte[] enc = encrypt(src); result = Base64.encodeBase64String(enc); } catch (IllegalBlockSizeException e) { throw new RuntimeException(e); } catch (BadPaddingException e) { throw new RuntimeException(e); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } return result; } /** * @param str * ? * @return String ? */ public static String decrypt(String str) { String result = null; if (!StringUtils.isEmpty(str)) { try { byte[] src = Base64.decodeBase64(str); byte[] dec = decrypt(src); result = new String(dec, DEFAULT_CHARSET); } catch (IllegalBlockSizeException e) { throw new RuntimeException(e); } catch (BadPaddingException e) { throw new RuntimeException(e); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } return result; } }