package com.lz.core.fe.util; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Base64; import java.util.logging.Level; import java.util.logging.Logger; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import com.lz.core.fe.exception.BlankException; /** * ASE加密 * @ClassName ASEUtil.java * @author longload * @date 2016年1月13日下午1:47:27 */ public class ASEUtil { private static final String DEFAULT_CODE="utf-8"; private static Logger logger =Logger.getLogger("ASEUtil"); public static void main(String[] args) throws Exception { String content = "{'name':'李健','userId':'3b8ab8b7-510a-4837-b77e-4061976a295c'}";//要加密的字符串 String key = "cypt"; //appNbr //加密 System.out.println(content.length()+":加密前:" + content); String aa = encryptUrlStr(content, key); System.out.println("aa:"+aa); String bb="WAdxm1Bmd1Yp7yM_ns4jEO36TimCrAWKuir7SitedvWBHTO1mCqHStRxKrBxnKv8i-cGEnb-W-tr8PGUupuEzmrG7TuCfdlinOnlA5DpG3A="; System.out.println("bb:"+bb); //解密 System.out.println("解密后:" + decryptUrlStr(bb,key)); } /** * 将字符串加密成可以url传输的字符串 * @param content加密的内容 * @param key密钥 * @return * @date 2016年1月13日下午1:43:46 * @author longload */ public static String encryptUrlStr(String content, String key)throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { logger.log(Level.INFO,content); byte[] encryptResult=encrypt(content,key); logger.log(Level.INFO,"baseBefore:"+new String(encryptResult,DEFAULT_CODE)); encryptResult= Base64.getUrlEncoder().encode(encryptResult); String str =new String(encryptResult,DEFAULT_CODE); logger.log(Level.INFO,"baseAfter:"+str); return str; } /** * 将url传输的字符串解密后返回String * @param content 解密内容 * @param key 密钥 * @return * @date 2016年1月13日下午1:38:41 * @author longload * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws UnsupportedEncodingException */ public static String decryptUrlStr(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException{ if (content==null) { throw new BlankException("解密内容为空!"); } logger.log(Level.INFO,"debaseBefore:"+content); byte[] contentBytes=Base64.getUrlDecoder().decode(content); logger.log(Level.INFO,"debaseAfter:"+new String(contentBytes,DEFAULT_CODE)); byte[] decryptResult= decrypt(contentBytes, key); String str=new String(decryptResult,DEFAULT_CODE); logger.log(Level.INFO,"decrypt:"+str); return str; } /** * 加密 * * @param content 需要加密的内容 * @param key 加密密码 * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException */ public static byte[] encrypt(String content, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { SecretKey secretKey =getKey(key); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec secretKeyspec = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 byte[] byteContent = content.getBytes(DEFAULT_CODE); cipher.init(Cipher.ENCRYPT_MODE, secretKeyspec);// 初始化 byte[] result = cipher.doFinal(byteContent); return result; // 加密 } /** * 获得解密key * @param key * @return * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException * @date 2016年1月15日下午2:33:47 * @author longload */ public static SecretKey getKey(String key) throws NoSuchAlgorithmException, UnsupportedEncodingException { try { KeyGenerator _generator = KeyGenerator.getInstance( "AES" ); _generator.init(128, new SecureRandom(strKey.getBytes())); return _generator.generateKey(); } catch (Exception e) { throw new RuntimeException( " 初始化密钥出现异常 " ); } return _generator.generateKey(); } /**解密 * @param content 待解密内容 * @param key 解密密钥 * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws UnsupportedEncodingException */ public static byte[] decrypt(byte[] content, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { SecretKey secretKey =getKey(key); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);// 初始化 byte[] result = cipher.doFinal(content); return result; // 加密 } /** * 将二进制转换成16进制 * @param buf * @return */ public static String parseByte2HexStr(byte buf[]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length; i++) { String hex = Integer.toHexString(buf[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } /**将16进制转换为二进制 * @param hexStr * @return */ public static byte[] parseHexStr2Byte(String hexStr) { if (hexStr.length() < 1) return null; byte[] result = new byte[hexStr.length()/2]; for (int i = 0;i< hexStr.length()/2; i++) { int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16); int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16); result[i] = (byte) (high * 16 + low); } return result; } }
在windows下可用正常使用但是在Linux下将会出错
将getKey方法替换为下面部分:
public static SecretKey getKey(String key) throws NoSuchAlgorithmException, UnsupportedEncodingException { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(key.getBytes(DEFAULT_CODE)); kgen.init(128, secureRandom); return kgen.generateKey(); }
原因:
SecureRandom 实现完全随操作系统本身的內部状态,除非调用方在调用 getInstance 方法之后又调用了 setSeed (使用填充方法,使其固定)方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。