抽象
这是涵盖Java加密算法的三部分博客系列的第1部分。 本系列介绍如何实现以下目标:
- 使用SHA–512散列
- 使用AES–256的单密钥对称加密
- 使用RSA–4096的公钥/私钥非对称加密
这第一篇文章详细介绍了如何实现SHA–512哈希。 让我们开始吧。
免责声明
这篇文章仅供参考。 在使用所提供的任何信息之前,请认真思考。 从中学到东西,但最终自己做出决定,风险自负。
要求
我使用以下主要技术完成了本文的所有工作。 您可能可以使用不同的技术或版本来做相同的事情,但不能保证。
- Java 1.8.0_152_x64
- NetBeans 8.2(内部版本201609300101)
- Maven 3.0.5(与NetBeans捆绑在一起)
下载
访问我的GitHub页面以查看我所有的开源项目。 这篇文章的代码位于项目中: thoth-cryptography
散列
关于
散列是一种单向密码算法,它接收任意长度的消息,并输出该消息的可重复,固定长度和单向摘要(哈希)。 作为单向方式,应该无法从哈希值中重新生成原始消息。 相同的消息将始终生成相同的哈希。
哈希可以用于验证原始消息。 哈希的一种常见用法是验证密码。 而不是存储密码本身,而是存储密码的哈希。 为了验证密码,在登录过程中将存储的哈希与输入密码的新哈希进行比较。
由于相同的消息会生成相同的哈希,因此将使用salt值使哈希更安全(Salt,2017,第1段)。 考虑多个用户使用相同密码的情况。 盐值与原始密码结合使用可实现唯一的哈希值。 这很重要,因为如果散列值曾经遭到破坏,则相同的哈希值会让黑客知道那些密码是相同的。
SHA–512
截至今天进行的研究似乎表明,哈希算法的最佳和最安全算法是SHA–512,它使用64位字(Secure Hash Algorithms,2017,第2段)。 让我们看一个例子。
注意请勿将MD5用作安全哈希。 它具有许多漏洞(MD5,2017年,第1段)。 将MD5的使用限制为校验和和数据验证。
例
清单1是ShaTest.java单元测试,演示了如何哈希。 清单2是执行哈希的Sha.java类。
清单1 – ShaTest.java类
package org.thoth.security.hash;import java.util.Optional;
import org.junit.Assert;
import org.junit.Test;/*** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class ShaTest {@Testpublic void test_hash_with_optional_to_hex() throws Exception {// setupString username = "mjremijan";String password = "super!secret";Sha sha = new Sha();// testString asHex= sha.hashToHex(password, Optional.of(username));// assertAssert.assertEquals("F38CD5290D11B20159E36740843A8D93CFDFA395CF594F328613EF5C7BA42D9EAC00BF3EE47B7E8CE1587040B36365F05C8E15E9392C288A1D7C4CFB66097848", asHex);}@Testpublic void test_hash_without_optional_to_hex() throws Exception {// setupString password = "super!secret";Sha sha = new Sha();// testString asHex= sha.hashToHex(password, Optional.empty());// assertAssert.assertEquals("516A1FE9D87FE5B953D91B48B1A2FFA5AE5F670914C1B6FE0835D8877918DC4E8BC8FB8CCD520DBA940C21B4F294DFD1B4EFF2E06AB110C6A06E35068251C1DD", asHex);}@Testpublic void test_hash_with_optional_to_base64() throws Exception {// setupString username = "mjremijan";String password = "super!secret";Sha sha = new Sha();// testString asBase64= sha.hashToBase64(password, Optional.of(username));// assertAssert.assertEquals("84ZVKQ0RSGFZ42DAHDQNK8/FO5XPWU8YHHPVXHUKLZ6SAL8+5HT+JOFYCECZY2XWXI4V6TKSKIODFEZ7ZGL4SA==", asBase64);}@Testpublic void test_hash_without_optional_to_base64() throws Exception {// setupString password = "super!secret";Sha sha = new Sha();// testString asBase64= sha.hashToBase64(password, Optional.empty());// assertAssert.assertEquals("UWOF6DH/5BLT2RTISAL/PA5FZWKUWBB+CDXYH3KY3E6LYPUMZVINUPQMIBTYLN/RTO/Y4GQXEMAGBJUGGLHB3Q==", asBase64);}
}
清单2 – Sha.java类
package org.thoth.security.hash;import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Optional;/*** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class Sha {public String hashToHex(String hashMe, Optional<String> salt)throws NoSuchAlgorithmException, UnsupportedEncodingException {byte[] bytes= hash(hashMe, salt);StringBuilder sp= new StringBuilder();for (int i = 0; i < bytes.length; i++) {sp.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));}return sp.toString().toUpperCase();}public String hashToBase64(String hashMe, Optional<String> salt)throws NoSuchAlgorithmException, UnsupportedEncodingException {return Base64.getEncoder().encodeToString(hash(hashMe, salt)).toUpperCase();}public byte[] hash(String hashMe, Optional<String> salt)throws NoSuchAlgorithmException, UnsupportedEncodingException {MessageDigest md= MessageDigest.getInstance("SHA-512");md.update(hashMe.getBytes("UTF-8"));salt.ifPresent(s -> {try { md.update(s.getBytes("UTF-8")); } catch (Exception e) {throw new RuntimeException(e);}});return md.digest();}
}
摘要
哈希很容易。 选择一种强大的哈希算法(例如SHA–512)来保护您的应用程序数据。 避免使用MD5来保护数据。 及时了解哪些算法强大且安全。 如果您使用的是较旧的算法存在漏洞或受到威胁,请更新您的应用程序。
参考文献
盐(加密)。 (2017年11月3日)。 维基百科。 取自https://en.wikipedia.org/wiki/Salt_(cryptography) 。
安全哈希算法。 (2017年11月25日)。 维基百科。 取自https://en.wikipedia.org/wiki/Secure_Hash_Algorithms 。
MD5。 (2017年11月22日)。 维基百科。 取自https://en.wikipedia.org/wiki/MD5 。
翻译自: https://www.javacodegeeks.com/2017/12/choosing-java-cryptographic-algorithms-part-1-hashing.html