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

消息摘要算法的编程使用

2016-03-05 15:36 405 查看
消息摘要:

消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。因此消息摘要保证了消息的完整性。消息摘要采用单向Hash 函数将需加密 的明文”摘要”成一串128bit的密文,这一串密文亦称为数字指纹(Finger Print),它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致 。这样这串摘要便可成为验证明文是否是”真身”的”指纹”了。

HASH函数的抗冲突性使得如果一段明文稍有变化,哪怕只更改该段落的一个字母,通过哈希算法作用后都将产生不同的值。而HASH算法的单向性使得要找到到哈希值相同的两个不 同的输入消息,在计算上是不可能的。所以数据的哈希值,即消息摘要,可以检验数据的完整性。哈希函数的这种对不同的输入能够生成不同的值的特性使得无法找到两个具有相同哈希值的输入。因此,如果两个文档经哈希转换后成为相同的值,就可以肯定它们是同一文档。 所以,当希望有效地比较两个数据块时,就可以比较它们的哈希值。例如,可以通过比较邮件发送前和发送后的哈希值来验证该邮件在传递时是否修改。

MD算法:

为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护,

MD(Message Digest) (md2,md4,md5) 128位

SHA算法:

安全哈希算法,主要适用于数字签名标准里面定义的数字签名算法

算法 摘要长度

SHA-1 160

SHA-256 256

SHA-384 384

SHA-512 512

HMAC算法:

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



算法 摘要长度

HmacMD5 128

HmacSHA1 160

HmacSHA256 256

HmacSHA384 384

HmacSHA512 512

总结:

1. 散列函数特征:

(1)输入任意长度数据,输出固定长度散列值,计算很容易,过程不可逆

(2)对于某数据,其散列值固定

(3)两个数据不同,则对应的散列值也不同

(4)两个散列值不同,则对应的原始输入数据也不同

下面是MessageDigestUtil 工具类:

package key.base64;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.DigestInputStream;
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[] result= md5.digest();
//转换成十六进制
String resultString =BytesToHex.fromBytesToHex(result);
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 result=dis.read(buffer, 0, 1024);
while (result!=-1) {
result=dis.read(buffer, 0, 1024);
}
//消息摘要对象
MessageDigest md=dis.getMessageDigest();
byte[] resultBytes=md.digest();
String resultStrings=BytesToHex.fromBytesToHex(resultBytes);
return resultStrings;
}

//利用SHA算法计算某一数据的消息摘要的哈希值
public static String encryptSHA(byte[] data) throws NoSuchAlgorithmException {
MessageDigest md=MessageDigest.getInstance("SHA-256");
md.update(data);
byte[] resultBytes=md.digest();
String resultStrings=BytesToHex.fromBytesToHex(resultBytes);
return resultStrings;

}

//生成秘钥
public static byte[] initHmacKey() throws Exception {
//秘钥生成器对象
KeyGenerator keyGen=KeyGenerator.getInstance("HmacMD5");
SecretKey secretKey=keyGen.generateKey();
//将秘钥编码成字节数组
return secretKey.getEncoded();
}

//利用Hmac方法对某一数据的的消息摘要进行加密
public static String encryptHmac(byte[] data,byte[] key) throws Exception{
//得到Hmac的秘钥
SecretKey secretKey=new SecretKeySpec(key, "HmacMD5");
Mac mac=Mac.getInstance("HmacMD5");
mac.init(secretKey);
byte[] resultBytes=mac.doFinal(data);

String resultStrings=BytesToHex.fromBytesToHex(resultBytes);
return resultStrings;
}
}


字节数组转化为十六进制BytesToHex 类:

package key;
public class BytesToHex {

public static String fromBytesToHex(byte[] resultBytes) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < resultBytes.length; i++) {
if (Integer.toHexString(0xFF & resultBytes[i]).length() == 1) {
builder.append("0").append(
Integer.toHexString(0xFF & resultBytes[i]));
} else {
builder.append(Integer.toHexString(0xFF & resultBytes[i]));
}
}
return builder.toString();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: