MAC算法原理与常用实现
看本文前,最好先看看之前的對(duì)于MD5算法和SHA算法的介紹。
本文目錄
- 定義
- 常見(jiàn)應(yīng)用場(chǎng)景
- 1、linux客戶(hù)端:SecureCRT
- 2、Google身份驗(yàn)證器
- 3、銀聯(lián)pos機(jī)終端
- 原理
- java實(shí)現(xiàn)和使用
定義
MAC(Message Authentication Codes),是一種消息摘要算法,也叫消息認(rèn)證碼算法。
這種算法的核心是基于秘鑰的散列函數(shù)。
可以理解為,MAC算法,是MD5算法和SHA算法的升級(jí)版,是在這兩種算法的基礎(chǔ)上,又加入了秘鑰的概念,更加安全。
所以,有時(shí)候又叫MAC算法為HMAC算法(keyed-Hash Message Authentication Codes),即含有秘鑰的散列算法。
常見(jiàn)的MAC算法有以下兩大類(lèi):
MD系列:HmacMD2、HmacMD4、HmacMD5
SHA系列:HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512
大致用法:
如下圖,發(fā)送端根據(jù)message和一個(gè)mac算法,生成mac秘鑰
將mac秘鑰和message同時(shí)發(fā)送
接收端收到message,用同樣的mac算法,得到mac秘鑰,
判斷自己生成mac秘鑰和接收到的mac秘鑰是否一致,從而判斷message是否一致
常見(jiàn)應(yīng)用場(chǎng)景
mac算法的應(yīng)用場(chǎng)景,相比MD和SHA系列,要更為復(fù)雜,高級(jí)一點(diǎn)。
1、linux客戶(hù)端:SecureCRT
SecureCRT就用到了MAC算法
2、Google身份驗(yàn)證器
服務(wù)提供商為每個(gè)用戶(hù)生成80位的密鑰(然而RFC 4226 §4要求使用128位并建議使用160位密鑰)。它以16位、26位或者32位base32的字符串亦或是二維碼的方式提供出來(lái)。客戶(hù)端使用此密鑰生成HMAC-SHA1。
具體可看維基百科的介紹
3、銀聯(lián)pos機(jī)終端
中國(guó)銀聯(lián)直聯(lián)POS終端規(guī)范下載鏈接
主要截圖如下:
原理
根據(jù)RFC 2104,HMAC的數(shù)學(xué)公式為:
其中:
H為密碼散列函數(shù)(如MD5或SHA-1)
K為密鑰(secret key)
m是要認(rèn)證的消息
K’是從原始密鑰K導(dǎo)出的另一個(gè)秘密密鑰(如果K短于散列函數(shù)的輸入塊大小,則向右填充(Padding)零;如果比該塊大小更長(zhǎng),則對(duì)K進(jìn)行散列)
|| 代表串接
⊕ 代表異或(XOR)
opad 是外部填充(0x5c5c5c…5c5c,一段十六進(jìn)制常量)
ipad 是內(nèi)部填充(0x363636…3636,一段十六進(jìn)制常量)
java實(shí)現(xiàn)和使用
import org.apache.commons.codec.binary.Hex;import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException;public class HmacMD5Util {public static void main(String[] args) throws IOException, NoSuchAlgorithmException {System.out.println(encodeString("123"));}public static String encodeString(String plainText) throws UnsupportedEncodingException {return encodeBytes(plainText.getBytes("utf-8"));}public static String encodeBytes(byte[] bytes) {try { // // JDK的獲取秘鑰 // byte[] key = getKey();// 指定秘鑰byte[] key = Hex.decodeHex(new char[]{'a', 'b', 'c', 'd'});SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacMD5");Mac mac = Mac.getInstance("HmacMD5");mac.init(secretKeySpec);byte[] b = mac.doFinal(bytes); // return Hex.encodeHexString(b);int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0) {i += 256;}if (i < 16) {buf.append("0");}buf.append(Integer.toHexString(i));}return buf.toString();} catch (Exception e) {e.printStackTrace();}return "";}public static byte[] getKey() throws NoSuchAlgorithmException {KeyGenerator hmacMD5 = KeyGenerator.getInstance("HmacMD5");SecretKey secretKey = hmacMD5.generateKey();String algorithm = secretKey.getAlgorithm();// algorithm=HmacMD5byte[] encoded = secretKey.getEncoded();return encoded;}}結(jié)果:
4b1dd5bb09ae59a17a65168da372c90e總結(jié)
以上是生活随笔為你收集整理的MAC算法原理与常用实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JavaScript历史与ECMAScr
- 下一篇: Spring的@Scheduled 动态