- ·上一篇文章:java中Base64编码解码的编程使用
- ·下一篇文章:使用session对象储存数据
消息摘要MD/SHA/HMAC的使用方法
-->
[t]消息摘要的概念:[/t]
唯一对应一个消息或文本的固定长度的值,由一个单向Hash加密函数对消息进行作用而产生。
消息摘要的分类:
(1)MD(Message Digest):消息摘要算法
(2)SHA(Secure Hash Algorithm):安全散列算法
(3)MAC(Message Authentication Code):消息认证码算法
应用:
验证数据完整性(防止在传输途中被篡改)
[t]MD 算法的编程使用[/t]
MD 算法的基本概念
为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护
2. MD 算法的种类
MD 系列算法(JDK)
算法 | 数据长度 | 摘要长度 |
MD2 | 任意 | 128 |
MD5 | 任意 | 128 |
MD 算法编程使用:
1 2 3 4 5 6 | // 初始化 MessageDigest MessageDigest md5 = MessageDigest.getInstance("MD5"); // 更新 md5.update(data); // 生成摘要 byte[] result= md5.digest(); |
[t]SHA 算法的编程使用[/t]
1. SHA 算法的基本概念
安全哈希算法,主要适用于数字签名标准里面定义的数字签名算法
2. SHA 算法的种类
SHA 系列算法(JDK)
算法 | 数据长度 | 摘要长度 |
SHA-1 | 任意 | 160 |
SHA-256 | 256 | |
SHA-384 | 384 | |
SHA-512 | 512 |
SHA 系列算法编程使用:
/
1 2 3 4 5 6 | / 初始化MessageDigest MessageDigest sha = MessageDigest.getInstance("SHA"); // 更新 sha.update(data); // 生成摘要 byte[] result= sha.digest(); |
[t]HMAC 算法的编程使用[/t]
引言:单一MD或SHA算法缺点?
摘要值容易被篡改!
HMAC 算法的基本概念
结合了MD5和SHA算法的优势,同时用密钥对摘要加密,是一种更为安全的消息摘要算法。
HMAC 算法的种类
HMAC 系列算法(JDK)
算法 | 数据长度 | 摘要长度 |
?HmacMD5 | 任意 | 128 |
?HmacSHA1 | 160 | |
HmacSHA256 | 256 | |
HmacSHA384 | 384 | |
HmacSHA512 | 512 |
如何生成密钥
2. 构建密钥
1 2 3 4 5 6 | // 初始化 KeyGenerator KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5"); // 产生密钥 SecretKey secretKey = keyGen.generateKey(); // 得到密钥字节数组 byte[] key = secretKey.getEncoded(); |
3. 执行消息摘要
1 2 3 4 5 6 7 8 | // 从字节数组还原密钥 SecretKey secretKey = new SecretKeySpec(key, "HmacMD5"); // 实例化 Mac Mac mac = Mac.getInstance("HmacMD5"); // 用密钥初始化 Mac mac.init(secretKey); // 执行消息摘要 byte[] result = mac.doFinal(data); |
总结:
1. 散列函数特征:
(1)输入任意长度数据,输出固定长度散列值,计算很容易,过程不可逆
(2)对于某数据,其散列值固定
(3)两个数据不同,则对应的散列值也不同
(4)两个散列值不同,则对应的原始输入数据也不同
java代码实现
MessageDigestUtil.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | package cn.k88; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.security.DigestInputStream; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class MessageDigestUtil { public static String encryptMD5(byte[] data) throws NoSuchAlgorithmException{ MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(data); byte[] resultBytes = md5.digest(); String resultString = BytesToHex.fromBytesToHex(resultBytes); return resultString; } public static String getMD5OfFile(String path) throws Exception{ FileInputStream fis = new FileInputStream(new File(path)); DigestInputStream dis = new DigestInputStream(fis, MessageDigest.getInstance("MD5")); // 流输入 byte[] buffer = new byte[1024]; int read = dis.read(buffer, 0, 1024); while (read != -1){ read = dis.read(buffer, 0, 1024); } MessageDigest md = dis.getMessageDigest(); byte[] resultBytes = md.digest(); String resultString = BytesToHex.fromBytesToHex(resultBytes); return resultString; } public static String encryptSHA(byte[] data) throws NoSuchAlgorithmException{ MessageDigest sha = MessageDigest.getInstance("SHA-512"); sha.update(data); byte[] resultBytes = sha.digest(); String resultString = BytesToHex.fromBytesToHex(resultBytes); return resultString; } public static byte[] initHmacKey() throws Exception{ KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA512"); SecretKey secretKey = keyGen.generateKey(); return secretKey.getEncoded(); } public static String encryptHmac(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException{ SecretKey secretKey = new SecretKeySpec(key, "HmacSHA512"); Mac mac = Mac.getInstance("HmacSHA512"); mac.init(secretKey); byte[] resultBytes = mac.doFinal(data); String resultString = BytesToHex.fromBytesToHex(resultBytes); return resultString; } } |
Main.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import java.io.IOException; package cn.k88; public class Main { //待加密的明文 public static final String DATA = "www.k88.net"; public static final String PATH = "mysql-installer-web-community-5.6.22.0.msi"; public static void main(String[] args) throws Exception { /* Test MD5 */ String md5Result = MessageDigestUtil.encryptMD5(DATA.getBytes()); System.out.println(DATA + ">>>MD5>>>" + md5Result); /* Test MD5 of File */ String fileMD5Result = MessageDigestUtil.getMD5OfFile(PATH); System.out.println("File MD5 : " + fileMD5Result); /* Test SHA */ String shaResult = MessageDigestUtil.encryptSHA(DATA.getBytes()); System.out.println(DATA + ">>>SHA>>>" + shaResult); /* Test HMAC */ byte[] hmacKey = MessageDigestUtil.initHmacKey(); System.out.println("HMAC KEY: " + BytesToHex.fromBytesToHex(hmacKey)); String hmacResult = MessageDigestUtil.encryptHmac(DATA.getBytes(), hmacKey); System.out.println(DATA + ">>>HMAC>>>" + hmacResult); } } |
消息摘要MD/SHA/HMAC的使用方法