加密算法一般分爲對稱性加密算法和非對稱性加密算法,對於對稱性加密算法,信息接收雙方都需事先知道密匙和加解密算法且其密匙是相同的,以後即是對數據進行 加解密了。非對稱算法與之不一樣,發送雙方A,B事先均生成一堆密匙,而後A將本身的公有密匙發送給B,B將本身的公有密匙發送給A,若是A要給B發送消 息,則先須要用B的公有密匙進行消息加密,而後發送給B端,此時B端再用本身的私有密匙進行消息解密,B向A發送消息時爲一樣的道理。java
DES是一種分組數據加密技術(先將數據分紅固定長度的小數據塊,以後進行加密),速度較快,適用於大量數據加密,而3DES是一種基於DES的加密算法,使用3個不一樣密匙對同一個分組數據塊進行3次加密,如此以使得密文強度更高。算法
相較於DES和3DES算法而言,AES算法有着更高的速度和資源使用效率,安全級別也較之更高了,被稱爲下一代加密標準。spring
RSA和DSA的安全性及其它各方面性能都差很少,而ECC較之則有着不少的性能優越,包括處理速度,帶寬要求,存儲空間等等。數組
這幾種算法只生成一串不可逆的密文,常常用其效驗數據傳輸過程當中是否通過修改,由於相同的生成算法對於同一明文只會生成惟一的密文,若相同算法生成的密文不一樣,則證實傳輸數據進行過了修改。一般在數據傳說過程前,使用MD5和SHA1算法均須要發送和接收數據雙方在數據傳送以前就知道密匙生成算法,而HMAC與之不一樣的是須要生成一個密匙,發送方用此密匙對數據進行摘要處理(生成密文),接收方再利用此密匙對接收到的數據進行摘要處理,再判斷生成的密文是否相同。安全
因爲對稱加密算法的密鑰管理是一個複雜的過程,密鑰的管理直接決定着他的安全性,所以當數據量很小時,咱們能夠考慮採用非對稱加密算法。app
在實際的操做過程當中,咱們一般採用的方式是:採用非對稱加密算法管理對稱算法的密鑰,而後用對稱加密算法加密數據,這樣咱們就集成了兩類加密算法的優勢,既實現了加密速度快的優勢,又實現了安全方便管理密鑰的優勢。dom
若是在選定了加密算法後,那採用多少位的密鑰呢?性能
通常來講,密鑰越長,運行的速度就越慢,應該根據的咱們實際須要的安全級別來選擇,通常來講,RSA建議採用1024位的數字,ECC建議採用160位,AES採用128爲便可。測試
import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; 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; public class AESUtil { public static byte[] encrypt(String content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 建立密碼器 byte[] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(byteContent); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } public static String encryptString(String content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 建立密碼器 byte[] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(byteContent); String encryptResultStr = parseByte2HexStr(result); return encryptResultStr; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } public static byte[] decrypt(byte[] content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 建立密碼器 cipher.init(Cipher.DECRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(content); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } public static String decrypt(String content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] decryptFrom = parseHexStr2Byte(content); byte[] result = cipher.doFinal(decryptFrom); return new String(result); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } 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(); } 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; } public static void main(String[] args) { String content = "test"; String password = "12345678"; // 加密 System.out.println("加密前:" + content); byte[] encryptResult = encrypt(content, password); String encryptResultStr = parseByte2HexStr(encryptResult); System.out.println("加密後:" + encryptResultStr); // 解密 byte[] decryptFrom = parseHexStr2Byte(encryptResultStr); byte[] decryptResult = decrypt(decryptFrom, password); System.out.println("解密後:" + new String(decryptResult)); String enStr = encryptString("123", "@#&^%-$#@Coupon#$%^&@*"); System.out.println(enStr); } }
import java.security.MessageDigest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; public abstract class EncodeUtil { private static Logger logger = LoggerFactory.getLogger(EncodeUtil.class); /** * 定義加密方式 */ private final static String KEY_SHA = "SHA"; private final static String MD5 = "MD5"; /** * SHA 加密 * * @param data 須要加密的字符串 * @return 加密以後的字符串 */ public static String sha(String data) { // 驗證傳入的字符串 if (StringUtils.isEmpty(data)) { return ""; } try { // 建立具備指定算法名稱的信息摘要 MessageDigest sha = MessageDigest.getInstance(KEY_SHA); // 使用指定的字節數組對摘要進行最後更新 sha.update(data.getBytes("utf-8")); // 完成摘要計算 byte[] bytes = sha.digest(); // 將獲得的字節數組變成字符串返回 return byteArrayToHexString(bytes); } catch (Exception e) { logger.error("字符串使用SHA加密失敗", e); return null; } } /** * MD5 加密 * * @param data 須要加密的字符串 * @return 加密以後的字符串 */ public static String md5(String source) { // 驗證傳入的字符串 if (StringUtils.isEmpty(source)) { return ""; } try { MessageDigest md = MessageDigest.getInstance(MD5); byte[] bytes = md.digest(source.getBytes("utf-8")); return byteArrayToHexString(bytes); } catch (Exception e) { logger.error("字符串使用Md5加密失敗" + source + "' to MD5!", e); return null; } } /** * 轉換字節數組爲十六進制字符串 * * @param bytes * 字節數組 * @return 十六進制字符串 */ private static String byteArrayToHexString(byte[] bytes) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { sb.append(Integer.toHexString((bytes[i] & 0xFF) | 0x100).toUpperCase().substring(1, 3)); } return sb.toString(); } /** * 測試方法 * * @param args */ public static void main(String[] args) throws Exception { String key = "123"; System.out.println(sha(key)); System.out.println(md5(key)); } }
參考:加密