MD5、SHA、HMAC這三種加密算法,是非可逆加密,就是不可解密的加密方法。我們通常只把他們作為加密的基礎。單純的以上三種的加密並不可靠。
MD5
MD5 -- message-digest algorithm 5 (信息-摘要算法)縮寫,廣泛用於加密和解密技術,常用於文件校驗。校驗?不管文件多大,經過MD5后都能生成唯一的MD5值。好比現在的ISO校驗,都是MD5校驗。怎么用?當然是把ISO經過MD5后產生MD5的值。一般下載linux-ISO的朋友都見過下載鏈接旁邊放着MD5的串。就是用來驗證文 件是否一致的。
Java實現代碼jdk版本的
import sun.misc.BASE64Encoder; import java.security.MessageDigest; public class Test { public static void main(String[] args) throws Exception{ encryptMD5("HELLO".getBytes()); System.out.println(new BASE64Encoder().encode(encryptMD5("HELLO".getBytes()))); } public static byte[] encryptMD5(byte[] data) throws Exception { MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(data); return md5.digest(); } }
通常我們不直接使用上述MD5加密。通常將MD5產生的字節數組交給BASE64再加密一把,得到相應的字符串。
spring也提供了 封裝類:
DigestUtils.md5DigestAsHex(password.getBytes())
SHA
SHA(Secure Hash Algorithm,安全散列算法),數字簽名等密碼學應用中重要的工具,被廣泛地應用於電子商務等信息安全領域。雖然,SHA與MD5通過碰撞法都被破解了, 但是SHA仍然是公認的安全加密算法,較之MD5更為安全。
java 實現SHA加密jdk版
/** * 利用java原生的摘要實現SHA256加密 * @param str 加密后的報文 * @return */ public static String getSHA256StrJava(String str){ MessageDigest messageDigest; String encodeStr = ""; try { messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(str.getBytes("UTF-8")); encodeStr = byte2Hex(messageDigest.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return encodeStr; } /** * 將byte轉為16進制 * @param bytes * @return */ private static String byte2Hex(byte[] bytes){ StringBuffer stringBuffer = new StringBuffer(); String temp = null; for (int i=0;i<bytes.length;i++){ temp = Integer.toHexString(bytes[i] & 0xFF); if (temp.length()==1){ //1得到一位的進行補0操作 stringBuffer.append("0"); } stringBuffer.append(temp); } return stringBuffer.toString(); }
Apache實現的:
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>${common-codec.version}</version> </dependency>
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; public class Test { /** * Apache SHA */ public static String getSHA256Str(String str){ MessageDigest messageDigest; String encdeStr = ""; try { messageDigest = DigestUtils.getSha256Digest(); byte[] hash=DigestUtils.digest(messageDigest,str.getBytes("UTF-8")); encdeStr = Hex.encodeHexString(hash); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return encdeStr; } }
HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個 標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然后傳輸。接收方利用與發送方共享的密鑰進行鑒別認證 等。
Java實現hmac
import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class Test { public static void main(String[] args) throws Exception{ String secrekey=initMacKey(); System.out.println(new String(encryptHMAC("hello".getBytes(),secrekey))); } /** * 初始化HMAC密鑰 * @return * @throws Exception */ public static String initMacKey() throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256"); SecretKey secretKey = keyGenerator.generateKey(); return new BASE64Encoder().encode(secretKey.getEncoded()); } /** * HMAC加密 * @param data * @param key * @return * @throws Exception */ public static byte[] encryptHMAC(byte[] data, String key) throws Exception { SecretKey secretKey = new SecretKeySpec(new BASE64Decoder().decodeBuffer(key), "HmacSHA256"); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return mac.doFinal(data); } }
apache 實現的工具類
同樣還是commons-codec包
具體可以參看包里的org.apache.commons.codec.digest.HmacUtils類
下面給出一個自封裝的HmacUtils工具類
import org.apache.commons.codec.binary.Base64; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * @Describe: Hmac加密工具類 */ public class HmacUtils { /** * 加密生成簽名 * @param data 簽名的格式 * @param key 秘鑰 * @return */ public static byte[] hmacSHA512(byte[] data, String key) { try { SecretKey secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA512"); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return mac.doFinal(data); } catch (Exception e) { return null; } } /** * base64編碼的變體,由於base64中的=、/和+不適合Url傳遞, * 因此需要將這三個符號替換掉,規則是去掉=,+替換為-,/替換為_ * @param stringBytes hmac(hmacSHA512) * @return */ public static String base64Url(byte[] stringBytes) { try { String base64Str = Base64.encodeBase64String(stringBytes); base64Str = base64Str.replace("=", ""); base64Str = base64Str.replace("+", "-"); base64Str = base64Str.replace("/", "_"); return base64Str; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } /** * SHA512 加密 * @param strText (用戶密碼明文 + salt) * @return */ public static byte[] sha512(final String strText) { // 是否是有效字符串 if (strText != null && strText.length() > 0) { try { // SHA 加密開始 // 創建加密對象 並指定加密類型 MessageDigest messageDigest = MessageDigest .getInstance("SHA-512"); // 傳入要加密的字符串 messageDigest.update(strText.getBytes("UTF-8")); // 得到 byte 數組 return messageDigest.digest(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return null; } /** * Base64加密 * @param stringbytes * @return */ public static String base64(byte[] stringbytes) { try { String base64Str = Base64.encodeBase64String(stringbytes); return base64Str; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }
以上就是這三種單向加密的介紹。