1. 程式人生 > >HMAC-SHA1簽名演算法(JAVA和PHP) base64簽名演算法(PHP)

HMAC-SHA1簽名演算法(JAVA和PHP) base64簽名演算法(PHP)

HMAC

根據RFC 2316(Report of the IAB,April 1998),HMAC(雜湊訊息身份驗證碼: Hashed Message Authentication Code)以及IPSec被認為是Interact安全的關鍵性核心協議。它不是雜湊函式,而是採用了將MD5或SHA1雜湊函式與共享機密金鑰(與公鑰/私鑰對不同)一起使用的訊息身份驗證機制。基本來說,訊息與金鑰組合並執行雜湊函式。然後執行結果與金鑰組合並再次執行雜湊函式。這個128位的結果被截斷成96位,成為MAC.。

hmac主要應用在身份驗證中,它的使用方法是這樣的: 
1. 客戶端發出登入請求(假設是瀏覽器的GET請求) 
2. 伺服器返回一個隨機值,並在會話中記錄這個隨機值 
3. 客戶端將該隨機值作為金鑰,使用者密碼進行hmac運算,然後提交給伺服器 
4. 伺服器讀取使用者資料庫中的使用者密碼和步驟2中傳送的隨機值做與客戶端一樣的hmac運算,然後與使用者傳送的結果比較,如果結果一致則驗證使用者合法 。
在這個過程中,可能遭到安全攻擊的是伺服器傳送的隨機值和使用者傳送的hmac結果,而對於截獲了這兩個值的黑客而言這兩個值是沒有意義的,絕無獲取使用者密碼的可能性,隨機值的引入使hmac只在當前會話中有效,大大增強了安全性和實用性。大多數的語言都實現了hmac演算法,比如php的mhash、python的hmac.py、java的MessageDigest類,在web驗證中使用hmac也是可行的,用js進行md5運算的速度也是比較快的。

SHA

安全雜湊演算法SHA (Secure Hash Algorithm)是美國國家標準和技術局釋出的國家標準FIPS PUB 180-1,一般稱為SHA-1。其對長度不超過264二進位制位的訊息產生160位的訊息摘要輸出,按512位元塊處理其輸入。 
SHA是一種資料加密演算法,該演算法經過加密專家多年來的發展和改進已日益完善,現在已成為公認的最安全的雜湊演算法之一,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預對映或資訊),並把它們轉化為長度較短、位數固定的輸出序列即雜湊值(也稱為資訊摘要或資訊認證程式碼)的過程。雜湊函式值可以說時對明文的一種“指紋”或是“摘要”所以對雜湊值的數字簽名就可以視為對此明文的數字簽名。

HMAC_SHA1

HMAC_SHA1(Hashed Message Authentication Code, Secure Hash Algorithm)是一種安全的基於加密hash函式和共享金鑰的訊息認證協議。它可以有效地防止資料在傳輸過程中被截獲和篡改,維護了資料的完整性、可靠性和安全性。HMAC_SHA1訊息認證機制的成功在於一個加密的hash函式、一個加密的隨機金鑰和一個安全的金鑰交換機制。 
HMAC_SHA1 其實還是一種雜湊演算法,只不過是用金鑰來求取摘要值的雜湊演算法。 
HMAC_SHA1演算法在身份驗證和資料完整性方面可以得到很好的應用,在目前網路安全也得到較好的實現。

 

JAVA(HMAC-SHA1加密演算法):

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

/**
 *
 * [Hmac-SHA1 簽名演算法]
 * @String  encryptText [加密字元源串]
 * @String  encryptKey  [加密金鑰]
 * @return [簽名值]
 */
public class HmacSHA1 {
	private static final String MAC_NAME = "HmacSHA1";
	public static final String ENCODING = "UTF-8";
	//簽名方法
	public static String HmacSHA1Encrypt(String encryptText,String encryptKey ) throws Exception{
        byte[] data = encryptKey.getBytes( ENCODING );
        SecretKey secretKey = new SecretKeySpec( data, MAC_NAME );
        Mac mac = Mac.getInstance( MAC_NAME );
        mac.init( secretKey );
        byte[] text = encryptText.getBytes( ENCODING );
        byte[] digest = mac.doFinal( text );
        return new String(Base64.encodeBase64(digest));
	}
}

PHP(HMAC-SHA1+base64加密演算法):

<?php
/**
 * [HmacSHA1Encrypt HMAC-SHA1加密演算法]
 * @param String $encryptText [加密文字源串]
 * @param String $encryptKey  [加密金鑰]
 * @return 簽名串值
 * 
 */
function HmacSHA1Encrypt(String $encryptText,String $encryptKey ){

	$signature = "";
	if(function_exists('hash_hmac')){

		$hash_hmac = hash_hmac("sha1",$encryptText,$encryptKey,true);
		$signature = base64_encode($hash_hmac);

	}else{

		$blocksize = 64;
		$hashfunc  = 'sha1';

		if(strlen($encryptKey) > $blocksize) {
			$encryptKey = pack("H*", $hashfunc($encryptKey));
		}

		$encryptKey = str_pad($encryptKey, $blocksize, chr(0x00));
		$ipad = str_repeat(chr(0x36), $blocksize);
		$opad = str_repeat(chr(0x5c), $blocksize);
		$hmac = pack("H*", $hashfunc(($encryptKey ^ $opad).pack('H*', $hashfunc(($encryptKey ^ $ipad).$str))));
		$signature = base64_encode($hmac);
	}
	return $signature;
}