- 區塊鏈底層設計Java實戰
- 牛冬編著
- 1546字
- 2019-07-25 11:59:22
3.2 哈希
3.2.1 散列函數簡介
哈希函數也稱為散列函數,在維基百科中的定義如下:
散列函數是可以將任意大小的數據映射到固定大小數據的任何函數。散列函數返回的值稱為散列值、哈希代碼、摘要或簡單散列。散列函數通常與哈希表配合使用,哈希表是計算機軟件中用于快速查找數據的常用數據結構。
作為加密算法的一種,散列函數是一種單向密碼體制,即一個從明文到密文的不可逆映射,只有加密過程,沒有解密過程。
散列函數的主要特點有:壓縮性強、計算簡單、計算結果單向性。壓縮性強是指對于任意大小的輸入內容,哈希值的長度很小,而且長度是固定位數的。計算簡單是指對于任意給定的消息,計算其哈希值都比較簡單。計算結果單向性是指對于給定的哈希值,無法倒推輸入的原始數值。這也是散列函數安全性的重要基礎。
當然,將無限內容壓縮到有限位數的取值范圍內,不可避免會出現不同的內容卻有相同哈希值的碰撞結果。因此抗碰撞性是一個良好的散列函數的必備條件。
目前,哈希算法主要有兩類:MD系列和SHA系列。MD(Message Digest,消息摘要)系列有MD4、MD5、HAVAL等,SHA(Secure Hash Algorithm,安全散列算法)系列有SHA1、SHA256等。其中,MD5是密碼學專家R.L.Rivest設計的,SHA是美國算法制定機構設計的。
常見的哈希算法有SHA-1算法、SHA-2算法、SHA-3算法,分別介紹如下。
1)SHA-1算法
SHA-1算法的輸入是最大長度小于264位的消息,輸入消息以512位的分組為單位進行處理,輸出是160位的消息摘要。SHA-1算法具有實現速度高、容易實現、應用范圍廣等優點。
2)SHA-2算法
SHA-2算法的輸出長度可取224位、256位、384位、512位,分別對應SHA-224、SHA-256、SHA-384、SHA-512。它還包含另外兩個算法:SHA-512/224、SHA-512/256。比之前的哈希算法具有更強的安全強度和更靈活的輸出長度,其中,SHA-256是常用算法。SHA-256算法的輸入是最大長度小于264位的消息,輸出是256位的消息摘要,輸入消息以512位的分組為單位進行處理。
3)SHA-3算法
美國政府選擇Keccak算法作為SHA-3算法的加密標準,因為Keccak算法擁有良好的加密性能以及抗解密能力。
4)RIPEMD算法
RIPEMD(RACE Integrity Primitives Evaluation Message Digest),即RACE原始完整性校驗消息摘要。RIPEMD使用MD4的設計原理,并針對MD4的算法缺陷進行了改進,1996年首次發布RIPEMD-128版本,它在性能上與SHA-1算法類似。
上述算法中,SHA-1算法已經破解,SHA-2算法是使用范圍較為廣泛的算法,經常用于數字簽名領域。對研發小伙伴而言,我們去開源網站下載源代碼的過程中完整性校驗就是基于哈希算法的。
在區塊鏈系統中,目前使用的主流哈希算法是SHA-256,下面將從實戰的角度,為讀者展示如何進行哈希計算。
3.2.2 SHA-256 Java實戰
我們可以用多種方法來實現用Java編寫SHA-256的哈希計算接口??梢曰贏pache commons-codec的工具類來實現SHA-256加密,也可以利用Hutool的工具類來實現SHA-256加密。
下面展示利用Apache commons-codec的工具類實現SHA-256加密的代碼和利用Hutool的工具類實現SHA-256加密的代碼,代碼如下:
package com.niudong.demo.util; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.binary.Hex; import cn.hutool.crypto.digest.DigestUtil; public class SHAUtil { /*** * 利用Apache commons-codec的工具類實現SHA-256加密 * * @param originalStr加密前的報文 * @return String加密后的報文 */ public static String getSHA256BasedMD(String originalStr) { MessageDigest messageDigest; String encdeStr = ""; try { messageDigest = MessageDigest.getInstance("SHA-256"); byte[] hash = messageDigest.digest(originalStr.getBytes("UTF-8")); encdeStr = Hex.encodeHexString(hash); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return encdeStr; } /*** * 利用Hutool的工具類實現SHA-256加密 * * @param originalStr加密前的報文 * @return String加密后的報文 */ public static String sha256BasedHutool(String originalStr) { return DigestUtil.sha256Hex(originalStr); } }
如上述代碼所示,我們實現了getSHA256BasedMD()和sha256BasedHutool()方法,下面編寫單元測試代碼對兩個方法進行測試,單元測試代碼如下:
package com.niudong.demo.util; import org.testng.Assert; import org.testng.annotations.Test; public class SHAUtilTest { /** * SHAUtil測試類 */ // 測試getSHA256方法 @Test public void testGetSHA256() { String originalStr = "區塊鏈是分布式數據存儲、點對點傳輸、共識機制、加密 算法等計算機技術的新型應用模式。"; Assert.assertEquals("3c8fede03b42a9a3186fb96d7f22a1862bcb00e445e0b2956 6c613590306e3da", SHAUtil.getSHA256BasedMD(originalStr)); } // 測試getSHA256方法 @Test public void testSha256BasedHutool() { String originalStr = "區塊鏈是分布式數據存儲、點對點傳輸、共識機制、加密 算法等計算機技術的新型應用模式。"; Assert.assertEquals("3c8fede03b42a9a3186fb96d7f22a1862bcb00e445e0b2956 6c613590306e3da", SHAUtil.sha256BasedHutool(originalStr)); } }
在IDE窗口右擊鼠標,在右鍵快捷菜單中單擊“Run As”,在彈出的下拉列表中選擇“TestNG test”,執行單元測試代碼。測試結果輸出如下:
PASSED: testGetSHA256 PASSED: testSha256BasedHutool =============================================== Default test Tests run: 2, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 2, Failures: 0, Skips: 0 =============================================== [TestNG] Time taken by org.testng.reporters. JUnitReportReporter@2d3fcdbd: 9 ms [TestNG] Time taken by org.testng.reporters. EmailableReporter2@1936f0f5: 12 ms [TestNG] Time taken by org.testng.reporters.jq.Main@62043840: 66 ms [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms [TestNG] Time taken by org.testng.reporters.XMLReporter@3567135c: 10 ms [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@180bc464: 54 ms Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
- 從零開始構建企業級RAG系統
- 深入淺出Electron:原理、工程與實踐
- C語言程序設計實訓教程
- 用Flutter極速構建原生應用
- Apex Design Patterns
- RabbitMQ Essentials
- Procedural Content Generation for C++ Game Development
- 一本書講透Java線程:原理與實踐
- Spring技術內幕:深入解析Spring架構與設計原理(第2版)
- Python 3 數據分析與機器學習實戰
- Machine Learning for Developers
- 深入解析Java編譯器:源碼剖析與實例詳解
- 算法設計與分析:基于C++編程語言的描述
- Java程序設計教程
- 百萬在線:大型游戲服務端開發