Java 加密解密之消息摘要算法(MD5 SHA MAC)
消息摘要
消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。因此消息摘要保证了消息的完整性。消息摘要采用单向Hash 函数将需加密 的明文"摘要"成一串128bit的密文,这一串密文亦称为数字指纹(Finger Print),它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致 。这样这串摘要便可成为验证明文是否是"真身"的"指纹"了。
HASH函数的抗冲突性使得如果一段明文稍有变化,哪怕只更改该段落的一个字母,通过哈希算法作用后都将产生不同的值。而HASH算法的单向性使得要找到到哈希值相同的两个不 同的输入消息,在计算上是不可能的。所以数据的哈希值,即消息摘要,可以检验数据的完整性。哈希函数的这种对不同的输入能够生成不同的值的特性使得无法找到两个具有相同哈希值的输入。因此,如果两个文档经哈希转换后成为相同的值,就可以肯定它们是同一文档。 所以,当希望有效地比较两个数据块时,就可以比较它们的哈希值。例如,可以通过比较邮件发送前和发送后的哈希值来验证该邮件在传递时是否修改。
消息摘要算法
消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。消息摘要算法不存在 密钥的管理与分发问题,适合于分布式网络相同上使用。由于其加密计算的工作量相当可观,所以以前的这种算法通常只用于数据量有限的情况下的加密,例如计算机的口令就是 用不可逆加密算法加密的。近年来,随着计算机相同性能的飞速改善,加密速度不再成为限制这种加密技术发展的桎梏,因而消息摘要算法应用的领域不断增加。
消息摘要算法的特点:
① 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。
② 消息摘要看起来是“随机的”。这些比特看上去是胡乱的杂凑在一起的。
③ 一般地,只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同;但相同的输入必会产生相同的输出。
④ 消息摘要函数是无陷门的单向函数,即只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本就找不到任何与原信息相关的信息。
⑤ 好的摘要算法,无法找到两条消息,是它们的摘要相同。
现有的消息摘要算法
消息摘要算法包含MD、SHA和MAC三大系列,常用于验证数据的完整性,是数据签名算法的核心算法。
MAC与MD和SHA不同,MAC是含有密钥的散列函数算法,我们也常把MAC称为HMAC。
JDK对消息摘要算法的支持
JDK6支持MD2/MD5/SHA/SHA256/SHA384/SHA512/HmacMD5/HmacSHA1/ HmacSHA256/HmacSHA384/HmacSHA512
使用到 十六进制工具类Hex.java 见: java byte数组与十六进制字符串互转
MD和SHA系列的java实现:
DigestUtils.java
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * reference apache commons <a * href="http://commons.apache.org/codec/">http://commons.apache.org/codec/</a> * * support MD2/MD5/SHA/SHA256/SHA384/SHA512 * @author Aub * */ public class DigestUtils { /** * 根据给定摘要算法创建一个消息摘要实例 * * @param algorithm * 摘要算法名 * @return 消息摘要实例 * @see MessageDigest#getInstance(String) * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ static MessageDigest getDigest(String algorithm) { try { return MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e.getMessage()); } } /** * 获取 MD5 消息摘要实例 * * @return MD5 消息摘要实例 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ private static MessageDigest getMd5Digest() { return getDigest("MD5"); } /** * 获取 SHA-1 消息摘要实例 * * @return SHA-1 消息摘要实例 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ private static MessageDigest getShaDigest() { return getDigest("SHA"); } /** * 获取 SHA-256 消息摘要实例 * * @return SHA-256 消息摘要实例 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ private static MessageDigest getSha256Digest() { return getDigest("SHA-256"); } /** * 获取 SHA-384 消息摘要实例 * * @return SHA-384 消息摘要实例 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ private static MessageDigest getSha384Digest() { return getDigest("SHA-384"); } /** * 获取 SHA-512 消息摘要实例 * * @return SHA-512 消息摘要实例 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ private static MessageDigest getSha512Digest() { return getDigest("SHA-512"); } /** * 使用MD5消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeMD5(byte[] data) { return getMd5Digest().digest(data); } /** * 使用MD5消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return 消息摘要(长度为32的十六进制字符串) */ public static String encodeMD5Hex(byte[] data) { return Hex.encodeHexStr(encodeMD5(data)); } /** * 使用SHA-1消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-1消息摘要(长度为20的字节数组) */ public static byte[] encodeSHA(byte[] data) { return getShaDigest().digest(data); } /** * 使用SHA-1消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-1消息摘要(长度为40的十六进制字符串) */ public static String encodeSHAHex(byte[] data) { return Hex.encodeHexStr(getShaDigest().digest(data)); } /** * 使用SHA-256消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-256消息摘要(长度为32的字节数组) */ public static byte[] encodeSHA256(byte[] data) { return getSha256Digest().digest(data); } /** * 使用SHA-256消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-256消息摘要(长度为64的十六进制字符串) */ public static String encodeSHA256Hex(byte[] data) { return Hex.encodeHexStr(encodeSHA256(data)); } /** * 使用SHA-384消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-384消息摘要(长度为43的字节数组) */ public static byte[] encodeSHA384(byte[] data) { return getSha384Digest().digest(data); } /** * 使用SHA-384消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-384消息摘要(长度为86的十六进制字符串) */ public static String encodeSHA384Hex(byte[] data) { return Hex.encodeHexStr(encodeSHA384(data)); } /** * 使用SHA-512消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-512消息摘要(长度为64的字节数组) */ public static byte[] encodeSHA512(byte[] data) { return getSha512Digest().digest(data); } /** * 使用SHA-512消息摘要算法计算消息摘要 * * @param data * 做消息摘要的数据 * @return SHA-512消息摘要(长度为128的十六进制字符串) */ public static String encodeSHA512Hex(byte[] data) { return Hex.encodeHexStr(encodeSHA512(data)); } }
参考 org.apache.commons.codec.digest.DigestUtils
下载地址: http://commons.apache.org/codec/download_codec.cgi
MAC系列的java实现
Hmac.java
import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * Hmac<br/> * algorithm HmacMD5/HmacSHA/HmacSHA256/HmacSHA384/HmacSHA512 * @author Aub */ public class Hmac { /** * 根据给定密钥生成算法创建密钥 * * @param algorithm * 密钥算法 * @return 密钥 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ private static byte[] getHmacKey(String algorithm){ //初始化KeyGenerator KeyGenerator keyGenerator = null; try { keyGenerator = KeyGenerator.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e.getMessage()); } //产生密钥 SecretKey secretKey = keyGenerator.generateKey(); //获得密钥 return secretKey.getEncoded(); } /** * 获取 HmaMD5的密钥 * * @return HmaMD5的密钥 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ public static byte[] getHmaMD5key(){ return getHmacKey("HmacMD5"); } /** * 获取 HmaSHA的密钥 * * @return HmaSHA的密钥 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ public static byte[] getHmaSHAkey(){ return getHmacKey("HmacSHA1"); } /** * 获取 HmaSHA256的密钥 * * @return HmaSHA256的密钥 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ public static byte[] getHmaSHA256key(){ return getHmacKey("HmacSHA256"); } /** * 获取 HmaSHA384的密钥 * * @return HmaSHA384的密钥 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ public static byte[] getHmaSHA384key(){ return getHmacKey("HmacSHA384"); } /** * 获取 HmaSHA512的密钥 * * @return HmaSHA384的密钥 * @throws RuntimeException * 当 {@link java.security.NoSuchAlgorithmException} 发生时 */ public static byte[] getHmaSHA512key(){ return getHmacKey("HmacSHA512"); } /** * 转换密钥 * * @param key 二进制密钥 * @param algorithm 密钥算法 * @return 密钥 */ private static Key toKey(byte[] key,String algorithm){ //生成密钥 return new SecretKeySpec(key, algorithm); } /** * 使用HmacMD5消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacMD5(byte[] data, Key key){ Mac mac = null; try { mac = Mac.getInstance("HmacMD5"); mac.init(key); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return new byte[0]; }catch (InvalidKeyException e) { e.printStackTrace(); return new byte[0]; } return mac.doFinal(data); } /** * 使用HmacMD5消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacMD5(byte[] data, byte[] key){ Key k = toKey(key, "HmacMD5"); return encodeHmacMD5(data, k); } /** * 使用HmacSHA消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA(byte[] data, Key key){ Mac mac = null; try { mac = Mac.getInstance("HmacSHA1"); mac.init(key); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return new byte[0]; }catch (InvalidKeyException e) { e.printStackTrace(); return new byte[0]; } return mac.doFinal(data); } /** * 使用HmacSHA消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA(byte[] data, byte[] key){ Key k = toKey(key, "HmacSHA1"); return encodeHmacSHA(data, k); } /** * 使用HmacSHA256消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA256(byte[] data, Key key){ Mac mac = null; try { mac = Mac.getInstance("HmacSHA256"); mac.init(key); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return new byte[0]; }catch (InvalidKeyException e) { e.printStackTrace(); return new byte[0]; } return mac.doFinal(data); } /** * 使用HmacSHA256消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA256(byte[] data, byte[] key){ Key k = toKey(key, "HmacSHA256"); return encodeHmacSHA256(data, k); } /** * 使用HmacSHA384消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA384(byte[] data, Key key){ Mac mac = null; try { mac = Mac.getInstance("HmacSHA384"); mac.init(key); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return new byte[0]; }catch (InvalidKeyException e) { e.printStackTrace(); return new byte[0]; } return mac.doFinal(data); } /** * 使用HmacSHA384消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA384(byte[] data, byte[] key){ Key k = toKey(key, "HmacSHA384"); return encodeHmacSHA384(data, k); } /** * 使用HmacSHA512消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA512(byte[] data, Key key){ Mac mac = null; try { mac = Mac.getInstance("HmacSHA512"); mac.init(key); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return new byte[0]; }catch (InvalidKeyException e) { e.printStackTrace(); return new byte[0]; } return mac.doFinal(data); } /** * 使用HmacSHA512消息摘要算法计算消息摘要 * * @param data 做消息摘要的数据 * @param key 密钥 * @return 消息摘要(长度为16的字节数组) */ public static byte[] encodeHmacSHA512(byte[] data, byte[] key){ Key k = toKey(key, "HmacSHA512"); return encodeHmacSHA512(data, k); } private static String showByteArray(byte[] data){ if(null == data){ return null; } StringBuilder sb = new StringBuilder("{"); for(byte b:data){ sb.append(b).append(","); } sb.deleteCharAt(sb.length()-1); sb.append("}"); return sb.toString(); } public static void main(String[] args) { // byte[] key = getHmaMD5key(); // byte[] key = getHmaSHAkey(); // byte[] key = getHmaSHA256key(); // byte[] key = getHmaSHA384key(); byte[] key = getHmaSHA512key(); System.out.println("加密密钥: byte[]:"+showByteArray(key).length()); String data = "Mac数据"; System.out.println("加密前数据: string:"+data); System.out.println("加密前数据: byte[]:"+showByteArray(data.getBytes())); System.out.println(); // byte[] encodeData = encodeHmacMD5(data.getBytes(), key); // byte[] encodeData = encodeHmacSHA(data.getBytes(), key); // byte[] encodeData = encodeHmacSHA256(data.getBytes(), key); // byte[] encodeData = encodeHmacSHA384(data.getBytes(), key); byte[] encodeData = encodeHmacSHA512(data.getBytes(), key); System.out.println("加密后数据: byte[]:"+showByteArray(encodeData).length()); System.out.println("加密后数据: byte[]:"+encodeData.length); System.out.println("加密后数据: hexStr:"+Hex.encodeHexStr(encodeData)); System.out.println(); } }
相关推荐
在压缩包中的"java加密、解密"文件中,很可能包含了实现这些加密解密操作的Java代码示例,包括类、方法和可能的测试用例。通过阅读和学习这些代码,开发者可以更好地理解和应用上述加密算法,同时了解如何在实际项目...
根据给定文件的信息,我们可以总结出关于C#中几种常用加密...通过以上代码示例,我们了解了如何在C#中实现DES加密解密、MD5和SHA256散列函数。这些技术在实际开发中非常有用,尤其是在保护用户数据的安全性和隐私方面。
本主题涉及的是在Java后台与前端JavaScript之间利用AES(Advanced Encryption Standard)进行加解密,以及前端的MD5(Message-Digest Algorithm 5)加密技术。以下是关于这些知识点的详细解释: 1. **AES加密**:...
在IT行业中,安全是至关重要的一个环节,尤其是在网络通信和数据传输中。微信小程序作为一款轻量级的...同时,也要关注加密算法的局限性,如MD5的碰撞风险和AES-ECB的模式可预测性,根据实际需求选择更安全的加密策略。
Java 中常用的加密算法 MD5,SHA,RSA Java 中常用的加密算法有多种,包括 MD5、SHA 和 RSA 等,这些算法在不同的应用场景中发挥着重要作用。下面将对这些算法进行详细的介绍和分析。 一、MD5 加密算法 MD5...
### Java中的MD5加密与“解密”技术详解 #### 一、MD5算法简介 MD5(Message-Digest Algorithm 5)是一种广泛使用的密码散列函数,可以产生一个128位(16字节)的散列值,通常用于确保数据的完整性和一致性。在...
总结,Java实现MD5加密算法主要是通过`java.security.MessageDigest`类,经过`getInstance("MD5")`获取MD5实例,然后使用`digest()`和`update()`方法处理数据,最终将二进制摘要转换为十六进制字符串。尽管MD5的安全...
### Java加密解密算法详解 #### 一、加密概述与应用 加密技术是信息安全领域中的关键技术之一,其核心在于通过特定算法对原始信息(明文)进行变换,使其成为不可直接阅读的形式(密文),从而保护信息在传输或...
本文将深入探讨Java中常见的几种加密解密算法:SHA算法、HMAC算法、DES算法、PBE算法、AES算法、RSA算法、数字签名以及D-H算法。 1. SHA(Secure Hash Algorithm)算法: SHA是一种散列函数,它能将任意长度的输入...
在给定的压缩包文件中,包含了几个常见的加密解密算法及其相关的源代码,包括SHA1、CRC32、IDEA和AES。接下来,我们将深入探讨这些算法的工作原理、应用以及它们在信息安全中的重要性。 首先,SHA1(安全哈希算法1...
4. MD5(Message-Digest Algorithm 5)和SHA系列:哈希函数,用于生成消息摘要,不适用于加密,但常用于验证数据完整性。 四、Java加密解密实例 以下是一个简单的AES加密解密示例: ```java import javax.crypto....
以下是关于Java MD5加密和解密的相关知识点: 1. **MD5原理**:MD5是由美国计算机科学家Ronald Rivest开发的一种加密散列函数,它将任意长度的数据转换为一个128位(16字节)的散列值,通常以32位的十六进制表示。...
包含Base64 ...包含摘要算法:MD2,MD4,MD5,SHA1,SHA2(SHA-224,SHA-256,SHA-384,SHA-512) 数字签名算法:RSA,DSA,ECDSA 详情请查看:http://blog.csdn.net/baidu_34012226/article/details/53331147
MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,用于产生一个固定长度的摘要,通常用于数据的加密和验证完整性。本Demo主要展示了如何在Android平台上进行MD5加密和解密操作。 MD5并不是一种加密算法...
标题“SHA MD5 Java和JavaScript加密的实现”指向的是如何在Java和JavaScript编程语言中应用这些哈希算法进行数据加密和验证。下面我们将详细介绍这两个算法以及在Java和JavaScript中的具体实现。 1. **SHA(安全...
MD5和SHA1是最常见的两种消息摘要算法。 - **MD5**:MD5算法产生的是128位的摘要,虽然它曾广泛使用,但由于近年来发现的碰撞攻击,它的安全性已大打折扣,不建议在安全敏感的场合使用。 - **SHA1**:SHA1算法产生...
常见的消息摘要算法有 SHA-1、MD5 等。 2. 签名和验证:数字签名算法包括签名和验证两个步骤。签名时使用私钥和待签名数据,验证时使用公钥、签名值和待签名数据。 五、Java 实现 Java 提供了多种加密算法和数字...
1. 引入`java.security.MessageDigest`类,它是Java标准库提供的用于生成各种消息摘要算法实例的类。 2. 创建MD5摘要实例:`MessageDigest.getInstance("MD5")`。 3. 更新要加密的数据:`digest.update(input....
java实现的sha256加密算法
根据提供的文件信息,本文将详细解析“JAVA源码很强的Java加密解密算法源码”这一主题中的关键知识点。从标题和描述来看,这是一份关于Java加密解密算法的源代码,通过百度网盘分享的方式提供给感兴趣的开发者。下面...