Message Authentication Code_消息認證碼算法java
內容來源於網絡算法
部份內容摘自博客:http://blog.csdn.net/zzminer/article/details/8574287安全
MAC算法結合了MD5和SHA算法的優點,並加入密鑰的支持,是一種更爲安全的消息摘要算法。網絡
MAC(Message Authentication Code,消息認證碼算法)是含有密鑰的散列函數算法,兼容了MD和SHA算法的特性,並在此基礎上加入了密鑰。函數
MAC算法主要集合了MD和SHA兩大系列消息摘要算法。MD系列的算法有HmacMD二、HmacMD四、HmacMD5三種算法;SHA系列的算法有HmacSHA一、HmacSHA22四、HmacSHA25六、HmacSHA384.HmacSHA512五種算法。工具
通過MAC算法獲得的摘要值也可使用十六進制編碼表示,其摘要值長度與參與實現的摘要值長度相同。例如,HmacSHA1算法獲得的摘要長度就是SHA1算法獲得的摘要長度,都是160位二進制,換算成十六進制編碼爲40位。編碼
案例:spa
某公司對來自網絡的欺詐性訂單叫苦連天。爲了改變這種局面,公司分配給每位客戶一個惟一的密鑰。客戶每下一個訂單,均須要提供訂單的MAC簽名(用這個密鑰計算得來)。由於公司有客戶的密鑰,因此天然可以驗證此訂單:1. 是否來自所聲明的客戶,2.是否被篡改了。.net
有不少種結合hash函數和密鑰的MAC實現方法。咱們假設H 是一個hash函數,‘+’ 表明鏈接運算. 下面的等式便表明一個能輕鬆實現MAC的方法:code
MAC= H( key + message )
可是,上述方法存在一個嚴重的安全漏洞:利用大部分hash函數的內部實現機制,很容易在不知道密鑰的狀況下,經過附加數據到message, 便能產生一個有效的MAC
固然還有其餘容易的替代方法,好比:MAC = H(message + key) 或者 H(key +message + key)。可是它們依舊存在安全隱患。
正是這些粗陋的MAC實現方法讓你們意識到須要一種靠得住的MAC實現方法,這即是HMAC的由來。
下面的定義抄自[RFC2104]:
HMAC (k,m) = H ( (k XOR opad ) + H( (k XOR ipad ) + m ) )
其中
H 是一個Hash函數, 好比, MD5, SHA-1and SHA-256,
k 是一個密鑰,從左到右用0填充到hash函數規定的block的長度,若是密鑰長度大於block的長度,就對先對輸入key做hash。
m 是須要認證的消息,
+ 表明「鏈接」運算,
XOR 表明異或運算,
opad 是外部的填充常數(0x5c5c5c…5c5c, 一個block長度的十六進制常數constant),
ipad 是內部的填充常數 (0x363636…3636,一個block長度的十六進制常數constant)。
特定HMAC實現須要選擇一個特定的hash函數。這些不一樣的HMAC實現一般標記爲:HMAC-MD5,HMAC-SHA1, HMAC-SHA256等等.
密碼學中,通訊實體雙方使用的一種驗證機制,保證消息數據完整性的一種工具。
安全性依賴於Hash函數,故也稱帶密鑰的Hash函數。
消息認證碼是基於密鑰和消息摘要【hash】所得到的一個值,目的是用於驗證消息的完整性,確認數據在傳送和存儲過程當中未受到主動攻擊
package encryption; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * MAC(Message Authentication Code,消息認證碼算法)是含有密鑰散列函數算法,兼容 * 了MD和SHA算法的特性,並在此基礎上加入了密鑰。所以,咱們也常把MAC稱爲HMAC * (keyed-Hash Message Authentication Code)。 * <p/> * Java 6實現 * HmacMD5 128 * HmacSHA1 160 * HmacSHA256 256 * HmacSHA384 384 * HmacSHA512 512 */ public class MACCoder { /** * 初始化HmacMD5密鑰 * * @return byte[] 密鑰 * @throws Exception */ public static byte[] initHmacMD5Key() throws Exception { // 初始化KeyGenerator KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5"); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 得到密鑰 return secretKey.getEncoded(); } /** * HmacMD5消息摘要 * * @param data 待作摘要處理的數據 * @param key 密鑰 * @return byte[] 消息摘要 * @throws Exception */ public static byte[] encodeHmacMD5(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacMD5"); // 實例化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); // 初始化Mac mac.init(secretKey); // 執行消息摘要 return mac.doFinal(data); } /** * 初始化HmacSHA1密鑰 * * @return byte[] 密鑰 * @throws Exception */ public static byte[] initHmacSHAKey() throws Exception { // 初始化KeyGenerator KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA1"); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 得到密鑰 return secretKey.getEncoded(); } /** * HmacSHA1消息摘要 * * @param data 待作摘要處理的數據 * @param key 密鑰 * @return byte[] 消息摘要 * @throws Exception */ public static byte[] encodeHmacSHA(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA1"); // 實例化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); // 初始化Mac mac.init(secretKey); // 執行消息摘要 return mac.doFinal(data); } /** * 初始化HmacSHA256密鑰 * * @return byte[] 密鑰 * @throws Exception */ public static byte[] initHmacSHA256Key() throws Exception { // 初始化KeyGenerator KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256"); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 得到密鑰 return secretKey.getEncoded(); } /** * HmacSHA256消息摘要 * * @param data 待作摘要處理的數據 * @param key 密鑰 * @return byte[] 消息摘要 * @throws Exception */ public static byte[] encodeHmacSHA256(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256"); // 實例化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); // 初始化Mac mac.init(secretKey); // 執行消息摘要 return mac.doFinal(data); } /** * 初始化HmacSHA384密鑰 * * @return byte[] 密鑰 * @throws Exception */ public static byte[] initHmacSHA384Key() throws Exception { // 初始化KeyGenerator KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA384"); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 得到密鑰 return secretKey.getEncoded(); } /** * HmacSHA384消息摘要 * * @param data 待作摘要處理的數據 * @param key 密鑰 * @return byte[] 消息摘要 * @throws Exception */ public static byte[] encodeHmacSHA384(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA384"); // 實例化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); // 初始化Mac mac.init(secretKey); // 執行消息摘要 return mac.doFinal(data); } /** * 初始化HmacSHA512密鑰 * * @return byte[] 密鑰 * @throws Exception */ public static byte[] initHmacSHA512Key() throws Exception { // 初始化 KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA512"); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 得到密鑰 return secretKey.getEncoded(); } /** * HmacSHA512消息摘要 * * @param data 待作摘要處理的數據 * @param key 密鑰 * @return byte[] 消息摘要 * @throws Exception */ public static byte[] encodeHmacSHA512(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA512"); // 實例化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); // 初始化Mac mac.init(secretKey); // 執行消息摘要 return mac.doFinal(data); } }
=============END=============