本篇树妖介绍Java项目中常用的几种数据校验算法。他们分是,MD5、SHA1、CRC32、HMACS-HA1,下面依次介绍。
一、MD5消息摘要
MD5算法是标准的,无论用那种语言结果都一样,无论输入放入数据有多长,结果都是16字节,然后再将16字节转成16进制输出。MD5并不是加密算法,而是一个单项的哈希算法。下面是简单的例子:
package my;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
/**
* md5消息摘要算法的使用
* @author andy
*
*/
public class MD5Demo
{
/**
* 数据的
* @throws NoSuchAlgorithmException
*/
public static void test1() throws NoSuchAlgorithmException
{
// 待处理的数据,任意长度
byte[] data = { 12, 8, 9, -1, 87, 0, -47, 99, 14, 54 };
//创建算法实例
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data);
byte[] code = md.digest();
//转成HEX显示
String result = Hex.encodeHexString(code , false);
System.out.println("检验码:" + result);
}
/**
* 文本的检验
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
*/
public static void test2() throws UnsupportedEncodingException, NoSuchAlgorithmException
{
String text = "你好!";
//获取byte数组
byte[] data = text.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data);
byte[] code = md.digest();
//需要添加jar包commons-codec-1.12.jar
String result = Hex.encodeHexString(code);
System.out.println("检验码:" + result);
}
/**
* 文件的检验
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public static void test3() throws IOException, NoSuchAlgorithmException
{
//创建算法实例
MessageDigest md = MessageDigest.getInstance("MD5");
File file = new File("C:\\Users\\andy\\Desktop\\hadoop-2.8.5.tar.gz");
InputStream input = new FileInputStream(file);
byte[] buf = new byte[1028];
while(true)
{
int n = input.read(buf);
if(n == 0)
continue;
if(n < 0)
break;
md.update(buf);
}
input.close();
byte[] code = md.digest();
String result = Hex.encodeHexString(code);
System.out.println("检验码:" + result);
}
}
二、SHA1算法
它的用法和MD5基本一致,不同的是,SHA1输出的是20个字节的检验码,所以它的强度更高,但是运行的速度会慢于MD5。
下面是简单的例子
package my;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
/**
* SHA1算法
* @author andy
*
*/
public class SHA1Demo
{
/**
* 算法摘要
* @throws NoSuchAlgorithmException
*/
public static void test1() throws NoSuchAlgorithmException
{
//待处理的数据
byte[] data = { 12, 8, 9, -1, 87, 0, -47, 99, 14, 54 };
//算法实例SHA1
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(data);
byte[] code = md.digest();
//转成HEX显示
String result = Hex.encodeHexString(code);
System.out.println("检验码:" + result);
}
/**
* 文本的检验
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
*/
public static void test2() throws UnsupportedEncodingException, NoSuchAlgorithmException
{
String text = "你好!";
//获取byte数组
byte[] data = text.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(data);
byte[] code = md.digest();
//需要添加jar包commons-codec-1.12.jar
String result = Hex.encodeHexString(code);
System.out.println("检验码:" + result);
}
/**
* 文件的检验
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public static void test3() throws IOException, NoSuchAlgorithmException
{
//创建算法实例
MessageDigest md = MessageDigest.getInstance("SHA1");
File file = new File("C:\\Users\\andy\\Desktop\\hadoop-2.8.5.tar.gz");
InputStream input = new FileInputStream(file);
byte[] buf = new byte[1028];
while(true)
{
int n = input.read(buf);
if(n == 0)
continue;
if(n < 0)
break;
md.update(buf);
}
input.close();
byte[] code = md.digest();
String result = Hex.encodeHexString(code);
System.out.println("检验码:" + result);
}
}
三、CRC32算法
全程为Cyclic Redundancy Check 循环冗余校验,结果为32位(4个字节)
用法演示
package my;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.zip.CRC32;
/**
* CRC32算法
* @author andy
*
*/
public class CRC32Demo
{
public static void test1()
{
//待处理的数据,任意长度
byte[] data = { 12, 8, 9, -1, 87, 0, -47, 99, 14, 54 };
//创建算法实例
CRC32 crc = new CRC32();
crc.update(data);
long value = crc.getValue();
//需要添加jar包commons-codec-1.12.jar
String result = Long.toHexString(value);
System.out.println("检验码:" + result);
}
/**
* 对字符串
* @throws UnsupportedEncodingException
*/
public static void test2() throws UnsupportedEncodingException
{
String text = "你好!";
byte[] data = text.getBytes("UTF-8");
//创建算法实例
CRC32 crc = new CRC32();
crc.update(data);
long value = crc.getValue();
String result = Long.toHexString(value);
System.out.println("检验码:" + result);
}
/**
* 对文件
* @throws IOException
*/
public static void test3() throws IOException
{
CRC32 crc = new CRC32();
File file = new File("C:\\Users\\andy\\Desktop\\hadoop-2.8.5.tar.gz");
InputStream input = new FileInputStream(file);
byte[] buf = new byte[1028];
while(true)
{
int n = input.read(buf);
if(n == 0)
continue;
if(n < 0)
break;
crc.update(buf);
}
input.close();
long value = crc.getValue();
String result = Long.toHexString(value);
System.out.println("检验码:" + result);
}
}
四、HMAC-SHA1签名
它是一种签名算法,密码相关的哈希算法。用于防止数据的伪造、假冒。校验算法可以检验数据的完整性,签名算法可以检验数据的真实性。它需要一个秘钥,当秘钥不用签名也不同;当然数据不同,签名也会不同。用法举例:
package my;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
/**
* HMACSHA1签名算法
* @author andy
*
*/
public class HMACSHA1Demo
{
public static void test1() throws NoSuchAlgorithmException, InvalidKeyException
{
//数据
byte[] data = { 12, 8, 9, -1, 87, 0, -47, 99, 14, 54 };
//秘钥
String key = "test2019";
//HMAC-SHA1 算法
Key keySpec = new SecretKeySpec(key.getBytes(), "HMACSHA1");
Mac mac = Mac.getInstance("HMACSHA1");
mac.init(keySpec);
//更新数据
mac.update(data);
//取得结果
byte[] code = mac.doFinal();
//需要添加jar包commons-codec-1.12.jar
String result = Hex.encodeHexString(code);
System.out.println("签名:" + result);
}
// 对字符串
public static void test2() throws Exception
{
// 待处理的字符串
String text = "你好!";
// 转成字节数据
byte[] data = text.getBytes("UTF-8");
// 密钥
String key = "test2019";
// HMAC-SHA1 算法
Key keySpec = new SecretKeySpec(key.getBytes(), "HMACSHA1");
Mac mac = Mac.getInstance("HMACSHA1");
mac.init(keySpec);
// 更新数据
mac.update(data);
// 取得最终结果
byte[] code = mac.doFinal();
String result = Hex.encodeHexString(code, false);
System.out.println("签名: " + result);
}
// 对文件
public static void test3() throws Exception
{
// 密钥
String key = "test2019";
// HMAC-SHA1 算法
Key keySpec = new SecretKeySpec(key.getBytes(), "HMACSHA1");
Mac mac = Mac.getInstance("HMACSHA1");
mac.init(keySpec);
// 读取文件
File file = new File("C:\\Users\\andy\\Desktop\\hadoop-2.8.5.tar.gz");
InputStream in = new FileInputStream(file);
byte[] buf = new byte[4096];
while (true)
{
int n = in.read(buf);
if (n <= 0)
break;
mac.update(buf, 0, n);
}
in.close();
// 取得最终结果
byte[] code = mac.doFinal();
String result = Hex.encodeHexString(code, false);
System.out.println("签名: " + result);
}
}