加密與安全_深入了解Hmac算法(消息認證碼)

文章目錄

  • Pre
  • HMAC概述
  • 常見的Hmac算法
  • Code
    • 隨機的key的生成 KeyGenerator
    • HmacMD5
      • 用Hmac算法取代原有的自定義的加鹽算法
    • HmacMD5 VS MD5
    • HmacSHA256

在這里插入圖片描述


Pre

加密與安全_深入了解哈希算法中我們提到,

存儲用戶的哈希口令時,要加鹽存儲,目的就在于抵御彩虹表攻擊。

digest = hash(input)

正是因為相同的輸入會產生相同的輸出,我們加鹽的目的就在于,使得輸入有所變化:

digest = hash(salt + input)

這個salt可以看作是一個額外的“認證碼”,同樣的輸入,不同的認證碼,會產生不同的輸出。因此,要驗證輸出的哈希,必須同時提供“認證碼”。

Hmac算法就是一種基于密鑰的消息認證碼算法,它的全稱是Hash-based Message Authentication Code,是一種更安全的消息摘要算法

Hmac算法總是和某種哈希算法配合起來用的。例如,我們使用MD5算法,對應的就是HmacMD5算法,它相當于“加鹽”的MD5:

HmacMD5md5(secure_random_key, input)

HMAC概述

HMAC(Hash-based Message Authentication Code)算法是一種基于哈希函數的消息認證碼算法,用于驗證消息的完整性和認證消息的發送者。它結合了哈希函數和密鑰,通過將密鑰與消息進行哈希運算來生成消息認證碼。

HMAC的計算過程如下:

  1. 首先,選擇一個適當的哈希函數(如MD5、SHA-1、SHA-256等)和一個密鑰。
  2. 將密鑰進行適當的填充和處理,以滿足哈希函數的輸入長度要求。
  3. 將消息與填充后的密鑰按照特定的方式進行組合。
  4. 對組合后的數據進行哈希運算。
  5. 將哈希結果作為消息認證碼輸出。

接收方在接收到消息后,也會使用相同的密鑰和哈希函數來計算消息的HMAC值,并與發送方發送的HMAC值進行比較。如果兩者一致,則消息完整且來自合法發送者;否則,可能存在消息被篡改或來自未經授權的發送者的風險。


通俗地講,HMAC算法就像是一種“密碼驗證器”,它確保數據在傳輸過程中不被篡改。

想象你要給朋友寄一封信,但你擔心信被別人篡改了。你可以用HMAC來解決這個問題。首先,你會在信封上寫下你的簽名。但這次不是用筆簽名,而是用一種特殊的技巧來生成一個“密鑰”。這個密鑰就像是你的個人密碼,只有你和你的朋友知道。

然后,你把這個簽名和信一起寄出去。你的朋友收到信后,也知道這個密鑰。他會用同樣的方法再次生成簽名,然后比對你寄來的簽名。如果兩個簽名一樣,說明信沒有被篡改,因為只有你和你的朋友知道這個特殊的“密碼”。

所以,HMAC就是通過一種雙重的“密碼”驗證機制,確保數據的完整性和安全性。HMAC算法具有較強的安全性和廣泛的應用,常用于網絡通信、數據傳輸、數字簽名等領域,以確保數據的完整性和安全性。


常見的Hmac算法

HMAC(Hash-based Message Authentication Code)算法可以與許多哈希函數結合使用,常用的哈希函數包括:

  1. HMAC-MD5:使用MD5哈希函數生成HMAC。
  2. HMAC-SHA1:使用SHA-1哈希函數生成HMAC。
  3. HMAC-SHA256:使用SHA-256哈希函數生成HMAC。
  4. HMAC-SHA512:使用SHA-512哈希函數生成HMAC。

這些算法提供了不同的哈希函數選項,可以根據安全性需求和性能考慮選擇適合的算法。通常情況下,較新的SHA-256和SHA-512算法被認為比MD5和SHA-1更安全,因此在安全要求較高的場景中更常用。


Code

隨機的key的生成 KeyGenerator

通過使用Java標準庫中的KeyGenerator生成安全的隨機密鑰,可以確保密鑰的隨機性和安全性,從而增強了加密算法的安全性。

KeyGenerator類提供了生成對稱密鑰的功能,可以根據指定的算法和安全隨機數生成器來生成密鑰。通常情況下,可以使用

  • KeyGenerator.getInstance(String algorithm)方法來獲取KeyGenerator實例,
  • 然后使用KeyGenerator.init(int keysize)方法指定密鑰的長度,
  • 最后通過KeyGenerator.generateKey()方法生成密鑰。

這樣生成的密鑰通常會具有足夠的長度和隨機性,能夠抵御常見的密碼攻擊,如窮舉搜索和字典攻擊。因此,使用Java標準庫中的KeyGenerator生成安全的隨機密鑰是一種推薦的做法,有助于提高系統的安全性。

HmacMD5

HmacMD5可以看作帶有一個安全的key的MD5。使用HmacMD5而不是用MD5加salt,有如下好處:

  • HmacMD5使用的key長度是64字節,更安全;
  • Hmac是標準算法,同樣適用于SHA-1等其他哈希算法;
  • Hmac輸出和原有的哈希算法長度一致。

可見,Hmac本質上就是把key混入摘要的算法。驗證此哈希時,除了原始的輸入數據,還要提供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{// 創建 KeyGenerator 實例并指定算法為 HmacMD5KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");// 生成隨機密鑰SecretKey key = keyGen.generateKey();// 打印隨機生成的密鑰byte[] skey = key.getEncoded();System.out.println("隨機生成的密鑰:" + new BigInteger(1, skey).toString(16));// 創建 Mac 實例并指定算法為 HmacMD5Mac 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標準庫生成HmacMD5算法的隨機密鑰,并計算給定消息(“HellArtisan”)的HMAC值。


用Hmac算法取代原有的自定義的加鹽算法

我們可以用Hmac算法取代原有的自定義的加鹽算法,因此,存儲用戶名和口令的數據庫結構如下:

| username | secret_key                        | password                              |
|----------|----------------------------------|---------------------------------------|
| bob      | a8c06e05f92e...5e16              | 7e0387872a57c85ef6dddbaa12f376de      |
| alice    | e6a343693985...f4be              | c1f929ac2552642b302e739bc0cdbaac      |
| tim      | f27a973dfdc0...6003              | af57651c3a8a73303515804d4af43790      |

每行包含用戶名(username)、隨機生成的密鑰(secret_key,長度為64字節),以及使用Hmac算法生成的密碼哈希值(password)。密鑰用于計算Hmac,確保密碼的安全性。

package com.artisan.securityalgjava.hmac;import java.util.Arrays;
import javax.crypto.*;
import javax.crypto.spec.*;/*** HMAC示例:使用預先生成的密鑰計算HMAC值* @author artisan*/
public class HmacVerifyTest {public static void main(String[] args) throws Exception {// 預先生成的密鑰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};// 創建SecretKey對象SecretKey key = new SecretKeySpec(hkey, "HmacMD5");// 獲取Mac實例并指定算法為HmacMD5Mac 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]}
}
// 創建SecretKey對象,使用預先生成的密鑰字節數組和算法名稱"HmacMD5"
SecretKey key = new SecretKeySpec(hkey, "HmacMD5");

這行代碼的作用是創建一個SecretKey對象,使用預先生成的密鑰字節數組(hkey)作為密鑰,同時指定算法名稱為"HmacMD5"。

這就是恢復SecretKey的代碼。


HmacMD5 VS MD5

相比于直接使用MD5哈希算法,使用HmacMD5算法需要經過一些額外的步驟來生成哈希值。

下面是使用HmacMD5算法生成哈希值的步驟:

  1. 通過名稱"HmacMD5"獲取KeyGenerator實例。
  2. 通過KeyGenerator創建一個SecretKey實例,這個密鑰將用于初始化Mac實例。
  3. 通過名稱"HmacMD5"獲取Mac實例。
  4. SecretKey初始化Mac實例,以指定使用的密鑰。
  5. Mac實例反復調用update(byte[])輸入數據,可以多次調用update方法以輸入數據的不同部分。
  6. 調用Mac實例的doFinal()方法獲取最終的哈希值。

這些步驟確保了使用HmacMD5算法生成哈希值時的安全性和正確性。 HmacMD5算法結合了MD5哈希算法和密鑰,提供了更高的安全性和防御性,適用于需要對消息進行完整性驗證和身份認證的場景。


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);// 將字節數組轉換成十六進制字符串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 {// 創建HmacSHA256實例Mac hmacSHA256 = Mac.getInstance("HmacSHA256");// 創建密鑰對象SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");// 使用密鑰初始化Mac實例hmacSHA256.init(secretKey);// 計算消息的HMAC-SHA256值并返回return hmacSHA256.doFinal(message.getBytes());}/*** 將字節數組轉換成十六進制字符串* @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值。最后,將計算得到的字節數組轉換成十六進制字符串,并打印輸出。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713695.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713695.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713695.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

操作系統系列學習——CPU管理的直觀想法

文章目錄 前言CPU管理的直觀想法 前言 一個本碩雙非的小菜雞,備戰24年秋招,計劃學習操作系統并完成6.0S81,加油! 本文總結自B站【哈工大】操作系統 李治軍(全32講) 老師課程講的非常好,感謝 【…

OpenLayers線性漸變和中心漸變(徑向漸變)

目錄 1.前言2.添加一個面要素3.線性漸變3.1 第一個注意點3.2 第二個注意點 4.中心漸變(徑向漸變)5.總結 1.前言 OpenLayers官網有整個圖層的漸變示例,但是沒有單個要素的漸變示例,我們這里來補充一下。OpenLayers中的漸變是通過fi…

python defaultdict

python中的dict是一個重要的數據類型,知道如何使用這個數據類型很簡單,但是這個類型使用過程中容易進入一些誤區,這篇文章主要對defaultdict方法的講解,深入的了解dict數據類型。 字典(dictionary)數據類型…

編譯鏈接實戰(22)C/C++代碼覆蓋率統計報告生成

文章目錄 GCOV 工具簡介gcov 使用lcov相關編譯選項 GCOV 工具簡介 gcov是一個測試代碼覆蓋率的工具,它是 gcc 自帶的查看代碼覆蓋率的工具。 與GCC結合使用,可以分析您的程序以幫助創建更高效、運行更快的代碼,并發現程序中未經測試的部分。…

PCIE 4.0 L0s/L1/L2

L0是PCIE設備正常工作的狀態,當設備鏈路處于非工作狀態可以跳轉大相應的低功耗狀態,L0s是一種可以快速恢復到L0的低功耗狀態;L1必須經過Reovery狀態才可以恢復到L0狀態;L2需要從Detect開始逐步進入到L0狀態。它們的恢復時間依次延…

麒麟銀河操作系統V10部署ffmpeg(也能用于Linux系統)

麒麟銀河操作系統V10部署ffmpeg(也能用于Linux系統) 部署ffmpeg用來處理視頻的各種操作 想使用ffmpeg,要先安裝nasm,yasm,x264之后,否則會報錯 nkvers 查看麒麟操作系統版本 cat /proc/version #查看linux版本信息 uname -a …

Android修行手冊-Chaquopy中opencv、numpy的初步應用

Unity3D特效百例案例項目實戰源碼Android-Unity實戰問題匯總游戲腳本-輔助自動化Android控件全解手冊再戰Android系列Scratch編程案例軟考全系列Unity3D學習專欄藍橋系列ChatGPT和AIGC 👉關于作者 專注于Android/Unity和各種游戲開發技巧,以及各種資源分…

SpringBoot源碼解讀與原理分析(三十八)SpringBoot整合WebFlux(一)WebFlux的自動裝配

文章目錄 前言第13章 SpringBoot整合WebFlux13.1 響應式編程與Reactor13.1.1 命令式與響應式13.1.2 異步非阻塞13.1.3 觀察者模式13.1.4 響應性13.1.5 響應式流13.1.6 背壓13.1.7 Reactor13.1.7.1 Publisher13.1.7.2 Subscriber13.1.7.3 Subscription13.1.7.4 Processor13.1.7.…

BF算法實現(Python,C++)

BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是將目標串S的第一個字符與模式串T的第一個字符進行匹配,若相等,則繼續比較S的第二個字符和 T的第二個字符;若不相等,則比…

Leetcoder Day32| 貪心算法part05

763.劃分字母區間 字符串 S 由小寫字母組成。我們要把這個字符串劃分為盡可能多的片段,同一字母最多出現在一個片段中。返回一個表示每個字符串片段的長度的列表。 示例: 輸入:S "ababcbacadefegdehijhklij"輸出:[9,7…

今日早報 每日精選15條新聞簡報 每天一分鐘 知曉天下事 3月2日,星期六

每天一分鐘,知曉天下事! 2024年3月2日 星期六 農歷正月廿二 1、 氣象局:3月份仍有5次冷空氣影響我國;全國多地或提前入春。 2、 央行:將外籍來華人員移動支付單筆交易限額由1000美元提高到5000美元。 3、 神舟十七號航…

全量知識系統問題及SmartChat給出的答復 之8 三套工具之3語法解析器 之1

Q19. 問題 : 解釋單詞解釋單詞occupied 的字典條目 (word-def occupiedinterest 5type EBsubclass SEBtemplate (script $Demonstrateactor nilobject nildemands nilmethod (scene $Occupyactor nillocation nil))fill (((actor) (top-of *actor-s…

【源碼】imx6ull實現觸摸屏單點實驗

一、本實驗實驗的器材: 1.正點原子imx6ull的阿爾法開發板v2.2 2.屏幕ALIENTEK 4.3 RGBLCD 二、實驗已經移植好的文件: 倉庫代碼:https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.文件說明 23_multitouch :驅動代…

aws平臺的ec2實例 GNU/Linux系統安裝docker流程

在AWS EC2實例上安裝Docker的流程與其他GNU/Linux系統基本相同。以下是在AWS EC2實例上安裝Docker的一般步驟: 登錄到AWS EC2實例: 使用SSH或者其他遠程登錄方式登錄到你的GNU/Linux實例。 更新系統包管理器: 對于基于Amazon Linux的系統&am…

常見Prometheus exporter部署

常見Prometheus exporter部署 Prometheus部署Node exporterProcess exporterRedis exporterMySQL exporterOracleDB exporter Prometheus部署 本地部署: wget https://github.com/prometheus/prometheus/releases/download/v*/prometheus-*.*-amd64.tar.gz tar xv…

java的jar打包docker鏡像,啟動加載

測試環境,打包鏡像 1,把jar包復制/data/liu/mssda.jar, cd到這個目錄下 2,創建Dockerfile文件,jdk17版本,內容如下 jdk8版本 FROM openjdk:8-jre-alpine WORKDIR /app COPY . /app CMD ["java", "-jar",…

最大奇約數(c++題解)

內存限制: 128 MiB時間限制: 100 ms標準輸入輸出題目類型: 傳統評測方式: 文本比較 題目描述 定義函數f(x)表示x的最大奇約數,這里x表示正整數。例如,f(20) 5,因為20的約數從小到大分別有&am…

奧地利羅馬尼亞媒體宣發稿對跨境出海推廣新聞營銷的意義

【本篇由言同數字科技有限公司原創】在當今全球化的時代,品牌跨境海外推廣已成為企業拓展國際市場的必要途徑。而奧地利和羅馬尼亞是歐洲重要的市場之一,通過在當地媒體上發表文章,可以幫助品牌成功打入這兩個市場,獲得更多的機會…

【YOLO v5 v7 v8 小目標改進】ODConv:在卷積核所有維度(數量、空間、輸入、輸出)上應用注意力機制來優化傳統動態卷積

ODConv:在卷積核所有維度(數量、空間、輸入、輸出)上應用注意力機制來優化傳統的動態卷積 提出背景傳統動態卷積全維動態卷積效果 小目標漲點YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改 論文:https://openreview.net/pdf?idDmpCfq6Mg…

leedcode刷題--day7(字符串)

23 文章講解 力扣地址 C class Solution { public:void reverseString(vector<char>& s) {int left 0;int right s.size() - 1; // right 應該初始化為 s.size() - 1while (left < right) {swap(s[left], s[right]); // 直接交換 s[left] 和 s[right] 的值lef…