MD5 和SHA1 這兩個摘要算法,使用很普遍,幾乎每個項目我們都會用這兩個算法來騙自己和騙用戶,看啊,我們保存的用戶密碼是加密的。對,存的不是明文,是密文。然而MD5真的安全麼?
上乾貨
JAVA生成MD5摘要的代碼:
MessageDigest md5 =MessageDigest.getInstance("MD5"); String messageStr="123456"; md5.update(messageStr.getBytes()); byte[] summery= md5.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < summery.length; i++) { if (Integer.toHexString(0xFF & summery[i]).length() == 1){ md5StrBuff.append("0").append( Integer.toHexString(0xFF & summery[i])); }else{ md5StrBuff.append(Integer.toHexString(0xFF & summery[i])); } } System.out.println(md5StrBuff.toString());
輸出結果 :
e10adc3949ba59abbe56e057f20f883e
但是MD5真的安全麼?
這裏我們可以老生長談一下,MD5是單向函數,不能反向求解,MD5是抗碰撞的。不存在兩不同的文本生成相同的摘要,但是可以用彩虹表查啊,通過窮舉明文並生成相應的摘要以鍵值對的形式存入數據庫我們就得到了一張彩虹表,然後我們只需要拿着密文去數據庫裏查
下面我們來看SHA 1
JAVA生成SHA1摘要的代碼:
MessageDigest md5 =MessageDigest.getInstance("SHA"); String messageStr="123456"; md5.update(messageStr.getBytes()); byte[] summery= md5.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < summery.length; i++) { if (Integer.toHexString(0xFF & summery[i]).length() == 1){ md5StrBuff.append("0").append( Integer.toHexString(0xFF & summery[i])); }else{ md5StrBuff.append(Integer.toHexString(0xFF & summery[i])); } } System.out.println(md5StrBuff.toString());
同樣的問題SHA1就真的安全麼?
SHA1和MD5是現在業內被用戶普遍認可的安全摘要算法,經常用來加密用戶密碼這類的敏感信息,作爲一個有良知的程序員我覺得這件事一定要說明白。MD5和SHA1在彩虹表面前脆弱的不堪一擊。
補充:
這裏再補充一個小小的細節,MD5和SHA1摘要算法生成的是字節數組,每一位裏存的是一個十六進制數,想要輸出出來不能直接new String因爲你不能把一個16進制數映射到UTF-8或者GBK字符集上,所以如果想以字符的形式輸出需要先轉換成16進制字符串再進行輸出。否則會輸出亂碼,道理前面已經說的很明白了。