详解Java中实现SHA1与MD5加密算法的基本方法
SHA1
packagecom.stone.security;
importjava.io.ByteArrayInputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.security.DigestInputStream;
importjava.security.DigestOutputStream;
importjava.security.MessageDigest;
importjava.util.Arrays;
importjavax.crypto.Mac;
importjavax.crypto.SecretKey;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.PBEKeySpec;
publicclassSHA{
publicstaticvoidmain(String[]args)throwsException{
encodeByMAC("中国oP……&*()…&802134…");
encodeBySHA("中国oP……&*()…&802134…");
shaFile();
}
/**
*使用MAC算法的消息摘要
*@paramdata
*@throwsException
*/
publicstaticvoidencodeByMAC(Stringdata)throwsException{
//KeyGeneratorkeyGen=KeyGenerator.getInstance("HmacSHA1");
//SecretKeykey=keyGen.generateKey();//这个每次生成的key不一样,此处不能使用
PBEKeySpeckeySpec=newPBEKeySpec("randomkey^(^&*^%$".toCharArray());
SecretKeyFactorykeyFactory=SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKeykey=keyFactory.generateSecret(keySpec);
/*
*此类提供“消息验证码”(MessageAuthenticationCode,MAC)算法的功能。
*MAC基于秘密密钥提供一种方式来检查在不可靠介质上进行传输或存储的信息的完整性。
*通常,消息验证码在共享秘密密钥的两个参与者之间使用,以验证这两者之间传输的信息。
*基于加密哈希函数的MAC机制也叫作HMAC。结合秘密共享密钥,
*HMAC可以用于任何加密哈希函数(如MD5或SHA-1)
*/
Macmac=Mac.getInstance("HmacSHA1");
//以下三种都可用
//Macmac=Mac.getInstance("HmacSHA256");
//Macmac=Mac.getInstance("HmacSHA384");
//Macmac=Mac.getInstance("HmacSHA512");
mac.init(key);
byte[]dest=mac.doFinal(data.getBytes());
System.out.println(dest.length);
System.out.println("MAC摘要:"+Arrays.toString(dest));
}
/**
*SHA1加密使用消息摘要MessageDigest处理
*@throwsException
*/
publicstaticStringencodeBySHA(Stringstr)throwsException{
MessageDigestsha1;
sha1=MessageDigest.getInstance("SHA1");
//以下三种不可用
//sha1=MessageDigest.getInstance("SHA256");
//sha1=MessageDigest.getInstance("SHA384");
//sha1=MessageDigest.getInstance("SHA512");
sha1.update(str.getBytes());//先更新摘要
byte[]digest=sha1.digest();//再通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。
/*
*使用指定的byte数组对摘要进行最后更新,然后完成摘要计算。
*也就是说,此方法首先调用update(input),
*向update方法传递input数组,然后调用digest()。
*/
//byte[]digest=sha1.digest(str.getBytes());
Stringhex=toHex(digest);
System.out.println("SHA1摘要:"+hex);
returnhex;
}
/**
*文件数据摘要
*@throwsException
*/
publicstaticvoidshaFile()throwsException{
MessageDigestmessageDigest=MessageDigest.getInstance("SHA1");
DigestOutputStreamdos=newDigestOutputStream(newFileOutputStream(newFile("abc.txt")),messageDigest);
dos.write("中华人民……&())f*(214)admin*".getBytes());
dos.close();
byte[]digest=messageDigest.digest();
System.out.println("使用流写文件,该文件的摘要为:"+toHex(digest));
DigestInputStreamdis=newDigestInputStream(newFileInputStream(newFile("abc.txt")),messageDigest);
byte[]buf=newbyte[100];
intlen;
while((len=dis.read(buf))!=-1){
System.out.println("读取到的数据为:"+newString(buf,0,len));
}
dis.close();
byte[]digest2=messageDigest.digest();
//当流读取完毕,即将文件读完了,这时的摘要才与写入时的一样
System.out.println("使用流读文件,该文件的摘要为:"+toHex(digest2));
}
/**
*sha1摘要转16进制
*@paramdigest
*@return
*/
privatestaticStringtoHex(byte[]digest){
StringBuildersb=newStringBuilder();
intlen=digest.length;
Stringout=null;
for(inti=0;i<len;i++){
//out=Integer.toHexString(0xFF&digest[i]+0xABCDEF);//加任意salt
out=Integer.toHexString(0xFF&digest[i]);//原始方法
if(out.length()==1){
sb.append("0");//如果为1位前面补个0
}
sb.append(out);
}
returnsb.toString();
}
}
MD5
MD5(MessageDigestAlgorithm5),即消息摘要算法第五版。消息摘要是一种算法:无论原始数据多长,消息摘要的结果都是固定长度的;是一种不可逆的算法
原始数据任意bit位的变化,都会导致消息摘要的结果有很大的不同,且根据结果推算出原始数据的概率极低。
消息摘要可以看作原始数据的指纹,指纹不同则原始数据不同。
packagecom.stone.security;
importjava.io.ByteArrayInputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.security.DigestInputStream;
importjava.security.DigestOutputStream;
importjava.security.MessageDigest;
importjava.util.Arrays;
importjavax.crypto.Mac;
importjavax.crypto.SecretKey;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.PBEKeySpec;
publicclassMD5{
publicstaticvoidmain(String[]args)throwsException{
encodeByMAC("中国oP……&*()…&802134…");
encodeByMd5("中国oP……&*()…&802134…");
md5File();
}
/**
*使用MAC算法的消息摘要
*@paramdata
*@throwsException
*/
publicstaticvoidencodeByMAC(Stringdata)throwsException{
//KeyGeneratorkeyGen=KeyGenerator.getInstance("HmacMD5");
//SecretKeykey=keyGen.generateKey();//这个每次生成的key不一样,此处不能使用
PBEKeySpeckeySpec=newPBEKeySpec("randomkey^(^&*^%$".toCharArray());
SecretKeyFactorykeyFactory=SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKeykey=keyFactory.generateSecret(keySpec);
/*
*此类提供“消息验证码”(MessageAuthenticationCode,MAC)算法的功能。
*MAC基于秘密密钥提供一种方式来检查在不可靠介质上进行传输或存储的信息的完整性。
*通常,消息验证码在共享秘密密钥的两个参与者之间使用,以验证这两者之间传输的信息。
*基于加密哈希函数的MAC机制也叫作HMAC。结合秘密共享密钥,
*HMAC可以用于任何加密哈希函数(如MD5或SHA-1)
*/
Macmac=Mac.getInstance("HmacMD5");
mac.init(key);
byte[]dest=mac.doFinal(data.getBytes());
System.out.println(dest.length);
System.out.println("MAC摘要:"+Arrays.toString(dest));
}
/**
*md5加密使用消息摘要MessageDigest处理
*@throwsException
*/
publicstaticStringencodeByMd5(Stringstr)throwsException{
MessageDigestmd5;
md5=MessageDigest.getInstance("MD5");
md5.update(str.getBytes());//先更新摘要
byte[]digest=md5.digest();//再通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。
/*
*使用指定的byte数组对摘要进行最后更新,然后完成摘要计算。
*也就是说,此方法首先调用update(input),
*向update方法传递input数组,然后调用digest()。
*/
//byte[]digest=md5.digest(str.getBytes());
Stringhex=toHex(digest);
System.out.println("MD5摘要:"+hex);
returnhex;
}
/**
*文件数据摘要
*@throwsException
*/
publicstaticvoidmd5File()throwsException{
MessageDigestmessageDigest=MessageDigest.getInstance("MD5");
DigestOutputStreamdos=newDigestOutputStream(newFileOutputStream(newFile("abc.txt")),messageDigest);
dos.write("中华人民……&())f*(214)admin*".getBytes());
dos.close();
byte[]digest=messageDigest.digest();
System.out.println("使用流写文件,该文件的摘要为:"+toHex(digest));
DigestInputStreamdis=newDigestInputStream(newFileInputStream(newFile("abc.txt")),messageDigest);
byte[]buf=newbyte[100];
intlen;
while((len=dis.read(buf))!=-1){
System.out.println("读取到的数据为:"+newString(buf,0,len));
}
dis.close();
byte[]digest2=messageDigest.digest();
//当流读取完毕,即将文件读完了,这时的摘要才与写入时的一样
System.out.println("使用流读文件,该文件的摘要为:"+toHex(digest2));
}
/**
*md5摘要转16进制
*@paramdigest
*@return
*/
privatestaticStringtoHex(byte[]digest){
StringBuildersb=newStringBuilder();
intlen=digest.length;
Stringout=null;
for(inti=0;i<len;i++){
//out=Integer.toHexString(0xFF&digest[i]+0xABCDEF);//加任意salt
out=Integer.toHexString(0xFF&digest[i]);//原始方法
if(out.length()==1){
sb.append("0");//如果为1位前面补个0
}
sb.append(out);
}
returnsb.toString();
}
}
PS:这里再为大家提供2款MD5加密工具,感兴趣的朋友可以参考一下:
MD5在线加密工具:
http://tools.jb51.net/password/CreateMD5Password
在线MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密工具:
http://tools.jb51.net/password/hash_md5_sha