您的位置:首页 > 编程语言

消息摘要的编程使用(MD5、SHA、HMAC)

2017-03-12 20:41 218 查看


消息摘要的概念: 

         唯一对应一个消息或文本的固定长度的值,由一个单向Hash加密函数对消息进行作用而产生


 消息摘要的分类:

(1)MD(Message Digest):消息摘要算法

(2)SHA(Secure Hash Algorithm):安全散列算法

(3)MAC(Message Authentication Code):消息认证码算法


消息摘要的日常应用

    验证文件的完整性


MD 算法的编程使用

    为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护,分为md2(128位),md5(128位),md2目前已被弃用。

package com.cry.md5;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.cry.ByteToHexUtil;

/**
* md5消息摘要(用于检测文件的完整性)
* @author zhangwx
*
*/
public class MD5Util {

/**
* 字符串md5
* @param data
* @return
* @throws NoSuchAlgorithmException
*/
public static String encryptMD5(byte[] data,String type) throws NoSuchAlgorithmException{
MessageDigest md5 = MessageDigest.getInstance(type);
md5.update(data);
byte[] result = md5.digest();
//转为16进制
String str = ByteToHexUtil.bytesToHexString(result);
return str;
}

/**
* 文件消息摘要
* @param path
* @return
* @throws NoSuchAlgorithmException
* @throws IOException
*/
public static String encryptMD5OfFile(String path,String type) throws NoSuchAlgorithmException, IOException{
FileInputStream in = new FileInputStream(new File(path));
DigestInputStream dis = new DigestInputStream(in, MessageDigest.getInstance(type));
byte[] buffer = new byte[1024];
int read = dis.read(buffer, 0, 1024);
while (read != -1){
read = dis.read(buffer, 0, 1024);
}
MessageDigest md5 = dis.getMessageDigest();
String result = ByteToHexUtil.bytesToHexString(md5.digest());
return result;
}

public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
String str = "test md5";
System.out.println(MD5Util.encryptMD5(str.getBytes(),"MD5"));
System.out.println(MD5Util.encryptMD5OfFile("D:/Installpackage/PieTTY 0.3.26.exe","MD5"));
}
}


package com.cry;

public class ByteToHexUtil {
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder("");
if(src==null||src.length<=0){
return null;
}
for (int i = 0; i < src.length; i++) {  int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
}


SHA算法的编程使用

    安全哈希算法,主要适用于数字签名标准里面定义的数字签名算法,SHA-1(160位),SHA-256(256位),

SHA-384(384位),SHA-512(512位),向上减少碰撞几率。

package com.cry.sha;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.cry.ByteToHexUtil;

public class SHAUtils {

/**
* sha安全消息摘要(相比md5更安全,其中SHA-256,SHA-384拥有更小的碰撞几率)
* @param data
* @param type
* @return
* @throws NoSuchAlgorithmException
*/
public static String encryptSHA(byte[] data,String type) throws NoSuchAlgorithmException{
MessageDigest sha = MessageDigest.getInstance(type);
sha.update(data);
//转16进制
String result = ByteToHexUtil.bytesToHexString(sha.digest());
return result;
}

public static void main(String[] args) throws NoSuchAlgorithmException {
String str = "test sha";
System.out.println(str+">>>SHA-1>>>"+SHAUtils.encryptSHA(str.getBytes(), "SHA"));
System.out.println(str+">>>SHA-256>>>"+SHAUtils.encryptSHA(str.getBytes(), "SHA-256"));
System.out.println(str+">>>SHA-384>>>"+SHAUtils.encryptSHA(str.getBytes(), "SHA-384"));
}
}



引言:单一MD或SHA算法缺点?

    摘要值容易被篡改!


HMAC 算法的基本概念 

         结合了MD5和SHA算法的优势,同时用密钥对摘要加密,是一种更为安全的消息摘要算法

package com.cry.hmac;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.cry.ByteToHexUtil;

/**
* 结合了MD5和SHA算法的优势,同时用密钥对摘要加密,是一种更为安全的消息摘要算法
* 秘钥只有发送方和接收方知道
* @author zhangwx
*
*/
public class HMACUtils {

/**
* 生成秘钥
* @param type
* @return
* @throws NoSuchAlgorithmException
*/
public static byte[] getSecretKey(String type) throws NoSuchAlgorithmException{
//初始化KeyGenerator
KeyGenerator keyGen = KeyGenerator.getInstance(type);
//生成秘钥
SecretKey secretKey = keyGen.generateKey();
//转化为字节数组
byte[] key = secretKey.getEncoded();
return key;
}

/**
* 消息摘要
* @param key
* @param type
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String encryptHmacMD5(byte[] key,String type) throws NoSuchAlgorithmException, InvalidKeyException{
//还原秘钥
SecretKey secretKey = new SecretKeySpec(key, type);
//实例化Mac
Mac mac = Mac.getInstance(type);
//用秘钥初始化Mac
mac.init(secretKey);
//获取消息摘要
byte[] result = mac.doFinal();
String str = ByteToHexUtil.bytesToHexString(result);
return str;
}

public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
String type = "HmacMD5";
byte[] secretKey = HMACUtils.getSecretKey(type);
System.out.println(HMACUtils.encryptHmacMD5(secretKey, type));

type = "HmacSHA1";
secretKey = HMACUtils.getSecretKey(type);
System.out.println(HMACUtils.encryptHmacMD5(secretKey, type));

type = "HmacSHA256";
secretKey = HMACUtils.getSecretKey(type);
System.out.println(HMACUtils.encryptHmacMD5(secretKey, type));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  消息摘要 加密