Message Authentication Code_消息認證碼算法

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位。編碼

 

MAC函數

 

MAC(Message Authentication Code)

案例: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的由來。

 

HMAC(Hash-based Message Authentication Code)

下面的定義抄自[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等等. 

 

MAC用於消息認證

 

消息認證碼

密碼學中,通訊實體雙方使用的一種驗證機制,保證消息數據完整性的一種工具。

安全性依賴於Hash函數,故也稱帶密鑰的Hash函數。

消息認證碼是基於密鑰和消息摘要【hash】所得到的一個值,目的是用於驗證消息的完整性,確認數據在傳送和存儲過程當中未受到主動攻擊

 

Java提供的MAC算法實現

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=============

相關文章
相關標籤/搜索