柚子快報激活碼778899分享:算法 Hmac 加密與安全
柚子快報激活碼778899分享:算法 Hmac 加密與安全
文章目錄
PreHMAC概述常見的Hmac算法Code隨機的key的生成 KeyGeneratorHmacMD5用Hmac算法取代原有的自定義的加鹽算法
HmacMD5 VS MD5HmacSHA256
Pre
加密與安全_深入了解哈希算法中我們提到,
存儲用戶的哈??诹顣r,要加鹽存儲,目的就在于抵御彩虹表攻擊。
digest = hash(input)
正是因為相同的輸入會產(chǎn)生相同的輸出,我們加鹽的目的就在于,使得輸入有所變化:
digest = hash(salt + input)
這個salt可以看作是一個額外的“認(rèn)證碼”,同樣的輸入,不同的認(rèn)證碼,會產(chǎn)生不同的輸出。因此,要驗證輸出的哈希,必須同時提供“認(rèn)證碼”。
Hmac算法就是一種基于密鑰的消息認(rèn)證碼算法,它的全稱是Hash-based Message Authentication Code,是一種更安全的消息摘要算法。
Hmac算法總是和某種哈希算法配合起來用的。例如,我們使用MD5算法,對應(yīng)的就是HmacMD5算法,它相當(dāng)于“加鹽”的MD5:
HmacMD5 ≈ md5(secure_random_key, input)
HMAC概述
HMAC(Hash-based Message Authentication Code)算法是一種基于哈希函數(shù)的消息認(rèn)證碼算法,用于驗證消息的完整性和認(rèn)證消息的發(fā)送者。它結(jié)合了哈希函數(shù)和密鑰,通過將密鑰與消息進(jìn)行哈希運算來生成消息認(rèn)證碼。
HMAC的計算過程如下:
首先,選擇一個適當(dāng)?shù)墓:瘮?shù)(如MD5、SHA-1、SHA-256等)和一個密鑰。將密鑰進(jìn)行適當(dāng)?shù)奶畛浜吞幚?,以滿足哈希函數(shù)的輸入長度要求。將消息與填充后的密鑰按照特定的方式進(jìn)行組合。對組合后的數(shù)據(jù)進(jìn)行哈希運算。將哈希結(jié)果作為消息認(rèn)證碼輸出。
接收方在接收到消息后,也會使用相同的密鑰和哈希函數(shù)來計算消息的HMAC值,并與發(fā)送方發(fā)送的HMAC值進(jìn)行比較。如果兩者一致,則消息完整且來自合法發(fā)送者;否則,可能存在消息被篡改或來自未經(jīng)授權(quán)的發(fā)送者的風(fēng)險。
通俗地講,HMAC算法就像是一種“密碼驗證器”,它確保數(shù)據(jù)在傳輸過程中不被篡改。
想象你要給朋友寄一封信,但你擔(dān)心信被別人篡改了。你可以用HMAC來解決這個問題。首先,你會在信封上寫下你的簽名。但這次不是用筆簽名,而是用一種特殊的技巧來生成一個“密鑰”。這個密鑰就像是你的個人密碼,只有你和你的朋友知道。
然后,你把這個簽名和信一起寄出去。你的朋友收到信后,也知道這個密鑰。他會用同樣的方法再次生成簽名,然后比對你寄來的簽名。如果兩個簽名一樣,說明信沒有被篡改,因為只有你和你的朋友知道這個特殊的“密碼”。
所以,HMAC就是通過一種雙重的“密碼”驗證機制,確保數(shù)據(jù)的完整性和安全性。HMAC算法具有較強的安全性和廣泛的應(yīng)用,常用于網(wǎng)絡(luò)通信、數(shù)據(jù)傳輸、數(shù)字簽名等領(lǐng)域,以確保數(shù)據(jù)的完整性和安全性。
常見的Hmac算法
HMAC(Hash-based Message Authentication Code)算法可以與許多哈希函數(shù)結(jié)合使用,常用的哈希函數(shù)包括:
HMAC-MD5:使用MD5哈希函數(shù)生成HMAC。HMAC-SHA1:使用SHA-1哈希函數(shù)生成HMAC。HMAC-SHA256:使用SHA-256哈希函數(shù)生成HMAC。HMAC-SHA512:使用SHA-512哈希函數(shù)生成HMAC。
這些算法提供了不同的哈希函數(shù)選項,可以根據(jù)安全性需求和性能考慮選擇適合的算法。通常情況下,較新的SHA-256和SHA-512算法被認(rèn)為比MD5和SHA-1更安全,因此在安全要求較高的場景中更常用。
Code
隨機的key的生成 KeyGenerator
通過使用Java標(biāo)準(zhǔn)庫中的KeyGenerator生成安全的隨機密鑰,可以確保密鑰的隨機性和安全性,從而增強了加密算法的安全性。
KeyGenerator類提供了生成對稱密鑰的功能,可以根據(jù)指定的算法和安全隨機數(shù)生成器來生成密鑰。通常情況下,可以使用
KeyGenerator.getInstance(String algorithm)方法來獲取KeyGenerator實例,然后使用KeyGenerator.init(int keysize)方法指定密鑰的長度,最后通過KeyGenerator.generateKey()方法生成密鑰。
這樣生成的密鑰通常會具有足夠的長度和隨機性,能夠抵御常見的密碼攻擊,如窮舉搜索和字典攻擊。因此,使用Java標(biāo)準(zhǔn)庫中的KeyGenerator生成安全的隨機密鑰是一種推薦的做法,有助于提高系統(tǒng)的安全性。
HmacMD5
HmacMD5可以看作帶有一個安全的key的MD5。使用HmacMD5而不是用MD5加salt,有如下好處:
HmacMD5使用的key長度是64字節(jié),更安全;Hmac是標(biāo)準(zhǔn)算法,同樣適用于SHA-1等其他哈希算法;Hmac輸出和原有的哈希算法長度一致。
可見,Hmac本質(zhì)上就是把key混入摘要的算法。驗證此哈希時,除了原始的輸入數(shù)據(jù),還要提供key。
package com.artisan.securityalgjava.hmac;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import java.math.BigInteger;
/**
* @author 小工匠
* @version 1.0
* @mark: show me the code , change the world
*/
public class HmacTest {
public static void main(String[] args) throws Exception{
// 創(chuàng)建 KeyGenerator 實例并指定算法為 HmacMD5
KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
// 生成隨機密鑰
SecretKey key = keyGen.generateKey();
// 打印隨機生成的密鑰
byte[] skey = key.getEncoded();
System.out.println("隨機生成的密鑰:" + new BigInteger(1, skey).toString(16));
// 創(chuàng)建 Mac 實例并指定算法為 HmacMD5
Mac mac = Mac.getInstance("HmacMD5");
// 初始化 Mac 實例
mac.init(key);
// 更新消息
mac.update("HellArtisan".getBytes("UTF-8"));
// 計算 HMAC 值
byte[] result = mac.doFinal();
// 打印 HMAC 值
System.out.println("HMAC 值:" + new BigInteger(1, result).toString(16));
}
}
使用Java標(biāo)準(zhǔn)庫生成HmacMD5算法的隨機密鑰,并計算給定消息(“HellArtisan”)的HMAC值。
用Hmac算法取代原有的自定義的加鹽算法
我們可以用Hmac算法取代原有的自定義的加鹽算法,因此,存儲用戶名和口令的數(shù)據(jù)庫結(jié)構(gòu)如下:
| username | secret_key | password |
|----------|----------------------------------|---------------------------------------|
| bob | a8c06e05f92e...5e16 | 7e0387872a57c85ef6dddbaa12f376de |
| alice | e6a343693985...f4be | c1f929ac2552642b302e739bc0cdbaac |
| tim | f27a973dfdc0...6003 | af57651c3a8a73303515804d4af43790 |
每行包含用戶名(username)、隨機生成的密鑰(secret_key,長度為64字節(jié)),以及使用Hmac算法生成的密碼哈希值(password)。密鑰用于計算Hmac,確保密碼的安全性。
package com.artisan.securityalgjava.hmac;
import java.util.Arrays;
import javax.crypto.*;
import javax.crypto.spec.*;
/**
* HMAC示例:使用預(yù)先生成的密鑰計算HMAC值
* @author artisan
*/
public class HmacVerifyTest {
public static void main(String[] args) throws Exception {
// 預(yù)先生成的密鑰
byte[] hkey = new byte[]{106, 70, -110, 125, 39, -20, 52, 56, 85, 9, -19, -72, 52, -53, 52, -45, -6, 119, -63,
30, 20, -83, -28, 77, 98, 109, -32, -76, 121, -106, 0, -74, -107, -114, -45, 104, -104, -8, 2, 121, 6,
97, -18, -13, -63, -30, -125, -103, -80, -46, 113, -14, 68, 32, -46, 101, -116, -104, -81, -108, 122,
89, -106, -109};
// 創(chuàng)建SecretKey對象
SecretKey key = new SecretKeySpec(hkey, "HmacMD5");
// 獲取Mac實例并指定算法為HmacMD5
Mac mac = Mac.getInstance("HmacMD5");
// 使用密鑰初始化Mac實例
mac.init(key);
// 更新消息
mac.update("HelloArtisan".getBytes("UTF-8"));
// 計算HMAC值
byte[] result = mac.doFinal();
// 打印HMAC值
System.out.println(Arrays.toString(result));
// [-22, 82, 110, 65, -70, -122, 93, 121, 48, 96, -40, -78, 126, 46, -47, 112]
}
}
// 創(chuàng)建SecretKey對象,使用預(yù)先生成的密鑰字節(jié)數(shù)組和算法名稱"HmacMD5"
SecretKey key = new SecretKeySpec(hkey, "HmacMD5");
這行代碼的作用是創(chuàng)建一個SecretKey對象,使用預(yù)先生成的密鑰字節(jié)數(shù)組(hkey)作為密鑰,同時指定算法名稱為"HmacMD5"。
這就是恢復(fù)SecretKey的代碼。
HmacMD5 VS MD5
相比于直接使用MD5哈希算法,使用HmacMD5算法需要經(jīng)過一些額外的步驟來生成哈希值。
下面是使用HmacMD5算法生成哈希值的步驟:
通過名稱"HmacMD5"獲取KeyGenerator實例。通過KeyGenerator創(chuàng)建一個SecretKey實例,這個密鑰將用于初始化Mac實例。通過名稱"HmacMD5"獲取Mac實例。用SecretKey初始化Mac實例,以指定使用的密鑰。對Mac實例反復(fù)調(diào)用update(byte[])輸入數(shù)據(jù),可以多次調(diào)用update方法以輸入數(shù)據(jù)的不同部分。調(diào)用Mac實例的doFinal()方法獲取最終的哈希值。
這些步驟確保了使用HmacMD5算法生成哈希值時的安全性和正確性。 HmacMD5算法結(jié)合了MD5哈希算法和密鑰,提供了更高的安全性和防御性,適用于需要對消息進(jìn)行完整性驗證和身份認(rèn)證的場景。
HmacSHA256
https://github.com/aperezdc/hmac-sha256/blob/master/hmac-sha256.c
package com.artisan.securityalgjava.hmac;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* @author 小工匠
* @version 1.0
* @mark: show me the code , change the world
*/
public class HmacSHA256Example {
public static void main(String[] args) {
// 要加密的消息
String message = "Hello, HMAC!";
// 密鑰
String key = "secretKey";
try {
// 計算HMAC-SHA256值
byte[] result = calculateHmacSHA256(message, key);
// 將字節(jié)數(shù)組轉(zhuǎn)換成十六進(jìn)制字符串
String hmacSHA256 = bytesToHex(result);
// 打印HMAC-SHA256值
System.out.println("HMAC-SHA256: " + hmacSHA256);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
}
/**
* 計算HMAC-SHA256值
* @param message
* @param key
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static byte[] calculateHmacSHA256(String message, String key)
throws NoSuchAlgorithmException, InvalidKeyException {
// 創(chuàng)建HmacSHA256實例
Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
// 創(chuàng)建密鑰對象
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");
// 使用密鑰初始化Mac實例
hmacSHA256.init(secretKey);
// 計算消息的HMAC-SHA256值并返回
return hmacSHA256.doFinal(message.getBytes());
}
/**
* 將字節(jié)數(shù)組轉(zhuǎn)換成十六進(jìn)制字符串
* @param bytes
* @return
*/
public static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
}
首先定義了要加密的消息和密鑰。然后,使用calculateHmacSHA256方法計算消息的HMAC-SHA256值。最后,將計算得到的字節(jié)數(shù)組轉(zhuǎn)換成十六進(jìn)制字符串,并打印輸出。
柚子快報激活碼778899分享:算法 Hmac 加密與安全
參考文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。