一、MD5
因为在消息摘要算法中,MD5应该最常用的,所以放在最前面。另外MD家族中除了MD5外,还有MD2和MD4,MD2和MD5在JDK中已经有实现,MD4则是在Bouncy Castle有实现。
public abstract class MD5 {
private static MessageDigest md;
static {
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 消息摘要处理,返回byte数组
*
* @param data
* @return
*/
public static byte[] encode2Bytes(byte[] data) {
try {
return md.digest(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 消息摘要处理,返回字符串
*
* @param algorithm
* @param data
*/
public static String encode2String(byte[] data) {
byte[] bytes = encode2Bytes(data);
if (bytes != null) {
return Hex.bytesToHexString(bytes);
}
return null;
}
/**
* 文件摘要处理
*
* @param file
* @return
*/
public static byte[] encode2Bytes(File file) {
DigestInputStream dis = null;
try {
dis = new DigestInputStream(new FileInputStream(file), md);
int size = 1024;
byte[] buf = new byte[size];
while (true) {
if (dis.read(buf, 0, size) < 0) {
break;
}
}
MessageDigest md = dis.getMessageDigest();
return md.digest();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (dis != null) {
try {
dis.close();
} catch (IOException e) {
}
dis = null;
}
}
return null;
}
/**
* 消息摘要处理,返回字符串
*
* @param file
* @return
* @throws Exception
*/
public static String encode2String(File file) {
byte[] bytes = encode2Bytes(file);
if (bytes != null) {
return Hex.bytesToHexString(bytes);
}
return null;
}
/**
*
* @param data
* @return
*/
public static byte[] encode2Bytes(String data) {
return encode2Bytes(StringUtil.getBytes(data));
}
/**
*
* @param data
* @return
*/
public static String encode2String(String data) {
return encode2String(StringUtil.getBytes(data));
}
}
二、SHA
SHA家族主要有SHA1、SHA224、SHA256、SHA384和SHA256,其中SHA224比较特殊一点,在Bouncy Castle有实现,其它的JDK中均有实现,使用与MD5保存一致。
public abstract class SHA1 {
private static MessageDigest md;
static {
try {
md = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
.....
}
三、MAC
MAC可以说是综合的MD和SHA的优点,增加了密钥支付,所以相对来说会更加安全。由于是综合MD和SHA,所以MAC家族主要有HmacMD2、HmacMD4、HmacMD5、HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512,其中HmacMD2、HmacMD4和HmacSHA224在在Bouncy Castle有实现。
public abstract class HmacSHA256 {
/**
* 算法名称
*/
private static final String ALGORITHM = "HmacSHA512";
/**
* 生成密钥
*
* @return
*/
public static byte[] getKeyBytes() {
try {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
if (kg != null) {
SecretKey key = kg.generateKey();
if (key != null) {
return key.getEncoded();
}
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* 生成密钥
*
* @return
*/
public static String getKeyString() {
return Hex.bytesToHexString(getKeyBytes());
}
/**
*
* @param data
* @param keybytes
* @return
*/
public static byte[] encode2Bytes(byte[] data, byte[] keybytes) {
if (data == null || data.length == 0 || keybytes == null || keybytes.length == 0) {
return null;
}
try {
SecretKey secKey = new SecretKeySpec(keybytes, ALGORITHM);
Mac mac = Mac.getInstance(secKey.getAlgorithm());
mac.init(secKey);
return mac.doFinal();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 消息摘要处理,返回byte数组
*
*/
public static byte[] encode2Bytes(byte[] data, String key) {
try {
return encode2Bytes(data, Hex.hexStringToBytes(key));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 消息摘要处理,返回字符串
*/
public static String encode2String(byte[] data, byte[] keybytes) {
byte[] bytes = encode2Bytes(data, keybytes);
if (bytes != null) {
return Hex.bytesToHexString(bytes);
}
return null;
}
/**
* 消息摘要处理,返回字符串
*/
public static String encode2String(byte[] data, String key) {
byte[] bytes = encode2Bytes(data, Hex.hexStringToBytes(key));
if (bytes != null) {
return Hex.bytesToHexString(bytes);
}
return null;
}
/**
*
* @param data
* @return
*/
public static byte[] encode2Bytes(String data, byte[] keybytes) {
return encode2Bytes(StringUtil.getBytes(data), keybytes);
}
/**
*
* @param data
* @return
*/
public static String encode2String(String data, String key) {
return encode2String(StringUtil.getBytes(data), Hex.hexStringToBytes(key));
}
}
四、其它
MD、SHA和MAC是消息摘要的主流,但还有一些其它的非主流算法,如RipeMD、Tiger等,当然这些算法在JDK均没有实现,有一部分可以在Bouncy Castle中找到。
附(两个工具类):
public class StringUtil {
/**
* 判断字符串是否为null或空
*
* @param str
* 待判断的字符串
* @return
*/
public static boolean isNullOrEmpty(String str) {
if (str != null) {
if (!"".equals(str.trim())) {
return false;
}
}
return true;
}
/**
* 数组转换成字符串
*
* @param data
* @return
*/
public static String getString(byte[] data) {
return getString(data, "UTF-8");
}
/**
*
* @param data
* @param encoding
* @return
*/
public static String getString(byte[] data, String encoding) {
try {
return new String(data, encoding);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 字符串转换成byte数组
*
* @param str
* 待转换的字符串
* @param encoding
* 编码
* @return
*/
public static byte[] getBytes(String str, String encoding) {
if (str == null) {
str = "";
}
try {
return str.getBytes(encoding);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使用默认UTF-8编码将字符串转换成byte数组
*
* @param str
* @return
*/
public static byte[] getBytes(String str) {
return getBytes(str, "UTF-8");
}
public static String toUtf8String(String string) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (c >= 0 && c <= 255) {
sb.append(c);
} else {
byte[] b;
try {
b = Character.toString(c).getBytes("utf-8");
} catch (Exception e) {
e.printStackTrace();
b = new byte[0];
}
for (int j = 0; j < b.length; j++) {
int k = b[j];
if (k < 0)
k += 256;
sb.append("%" + Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
}
}
public class Hex {
/**
* Convert byte[] to hex
* string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。
*
* @param src
* byte[] data
* @return hex string
*/
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();
}
/**
* Convert hex string to byte[]
*
* @param hexString
* the hex string
* @return byte[]
*/
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* Convert char to byte
*
* @param c
* char
* @return byte
*/
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}