MD5(信息摘要算法5)与SHA(安全散列算法)都属于数字摘要算法。数字摘要唯一对应一个消息或文本的固定长度的值,他由一个单向Hash函数对消息进行计算产生。
MD5摘要的长度是128位二进制,即32位十六进制;SHA的长度为160位二进制,即40位十六进制。
下面是基于Java的MD5与SHA-1算法的使用:
package com.ghs.secure;
import java.security.MessageDigest;
public class SecurityUtils {
/**
* MD5加密
* @param content
* @return
* @throws Exception
*/
public static String md5(String content) throws Exception{
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] bytes = digest.digest(content.getBytes("utf-8"));
return CodingUtils.bytes2hex(bytes);
}
/**
* SHA-1加密
* @param content
* @return
* @throws Exception
*/
public static String sha1(String content) throws Exception{
MessageDigest digest = MessageDigest.getInstance("SHA-1");
byte[] bytes = digest.digest(content.getBytes());
return CodingUtils.bytes2hex(bytes);
}
}
由于计算出的摘要需要转换成字符串,可能会生成一些无法显示和网络传输的控制字符,因此需要对生成的摘要进行编码,常用的编码方式包括十六进制编码和Base64编码。
十六进制编码是将二进制转换为十六进制,每4位二进制对应一位十六进制;Base64编码规定每6位为一个单元,对应某个可打印的字符,例如:三个字节有24位,那么需要4个可打印的字符。
下面是基于Java的十六进制编码和Base64编码的使用:
package com.ghs.secure;
import java.io.IOException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* 十六进制的编码与解码
* BASE64编码与解码
* @author liu
*
*/
public class CodingUtils {
/**
* 十六进制编码
* @param bytes
* @return
*/
public static String bytes2hex(byte[] bytes){
StringBuilder hex = new StringBuilder();
for(int i=0; i<bytes.length; i++){
int b = Math.abs(bytes[i]);//取绝对值
if(bytes[i]<0){//是否为负数
b = b | 0x80;
}
//b & 0xff用于截取整型的后两个字节
String temp = Integer.toHexString(b & 0xff);
//使用toHexString()函数,二进制0000不会被考虑(例如:00001000只会被转换为'8',而不是'08')
//当遇到这种二进制串时,手动在前面添加'0'
if(temp.length()==1){
hex.append("0");
}
hex.append(temp.toLowerCase());
}
return hex.toString();
}
/**
* 十六进制解码
* @param hex
* @return
*/
public static byte[] hex2bytes(String hex){
byte[] bytes = new byte[hex.length()/2];
for(int i=0; i<hex.length(); i=i+2){
String sub = hex.substring(i, i+2);
//将十六进制转换为整型
int inte = Integer.parseInt(sub, 16);
if(inte > 127){
if(inte == 128){
inte = -128;
}else{
//inte & 0x7F用于截取整型的后两个字节
inte = 0 - (inte & 0x7F);
}
}
byte b = (byte) inte;
bytes[i/2] = b;
}
return bytes;
}
/**
* BASE64编码
* @param bytes
* @return
*/
public static String bytes2base64(byte[] bytes){
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(bytes);
}
/**
* BASE64解码
* @param base64
* @return
* @throws IOException
*/
public static byte[] base642byte(String base64) throws IOException{
BASE64Decoder decoder = new BASE64Decoder();
return decoder.decodeBuffer(base64);
}
}