验证数据完整性——消息摘要算法

消息摘要算法包含MD(Message Digest,消息摘要算法)、SHA(Secure Hash Algorithm,安全散列算法)和MAC(Message Authentication Code,消息认证码算法)共3大系列,常用于验证数据的完整性,是数字签名算法的核心算法。

消息摘要算法又称为散列算法,其核心在于散列函数的单向性。即通过散列函数可获得对应的散列值,但不可通过该散列值反推原始信息。这是消息摘要算法的安全性的根本所在。

MD算法的使用

Sun中支持MD2和MD5算法,Bouncy Castle还支持MD4算法,Commons Codec的DigestUtils是对Sun提供的MessageDigest的一次封装,实现了MD5和SHA系列消息摘要算法的实现。

算法 摘要长度 备注
MD2 128 JAVA
MD5 同上 JAVA
MD4 ... BC

下面示例演示了MD5的处理。另外,对消息做MD5Hex处理后,得到的摘要值都是32位的十六进制字符串。

import org.apache.commons.codec.digest.DigestUtils;

public abstract class MD5Coder {

    /**
     * MD5加密
     * 
     * @param data
     *            待加密数据
     * @return byte[] 消息摘要
     * 
     * @throws Exception
     */
    public static byte[] encodeMD5(String data) throws Exception {

        // 执行消息摘要
        return DigestUtils.md5(data);
    }

    /**
     * MD5加密
     * 
     * @param data
     *            待加密数据
     * @return byte[] 消息摘要
     * 
     * @throws Exception
     */
    public static String encodeMD5Hex(String data) throws Exception {

        // 执行消息摘要
        return DigestUtils.md5Hex(data);
    }
}

用于校验文件的MD5值示例:
文件为 mysql-essential-5.1.38-win32.msi,存放于D盘根目录,MD5值为5a077abefee447cbb271e2aa7f6d5a47。

public class MD5Test {

    /**
     * 验证文件的MD5值
     * 
     * @throws Exception
     */
    @Test
    public void testByMessageDigest() throws Exception {
        // 文件路径
        String path = "D:\\mysql-essential-5.1.38-win32.msi";

        // 构建文件输入流
        FileInputStream fis = new FileInputStream(new File(path));

        // 初始化MessageDigest,并指定MD5算法
        DigestInputStream dis = new DigestInputStream(fis, MessageDigest
                .getInstance("MD5"));

        // 流缓冲大小
        int buf = 1024;

        // 缓冲字节数组
        byte[] buffer = new byte[buf];

        // 当读到值大于-1就继续读
        int read = dis.read(buffer, 0, buf);

        while (read > -1) {
            read = dis.read(buffer, 0, buf);
        }

        // 关闭流
        dis.close();

        // 获得MessageDigest
        MessageDigest md = dis.getMessageDigest();

        // 摘要处理
        byte[] b = md.digest();

        // 十六进制转换
        String md5hex = Hex.encodeHexString(b);

        // 验证
        assertEquals(md5hex, "5a077abefee447cbb271e2aa7f6d5a47");
    }

    /**
     * 验证文件的MD5值
     * 
     * @throws Exception
     */
    @Test
    public void testByDigestUtils() throws Exception {
        // 文件路径
        String path = "D:\\mysql-essential-5.1.38-win32.msi";

        // 构建文件输入流
        FileInputStream fis = new FileInputStream(new File(path));

        // 使用DigestUtils做MD5Hex处理
        String md5hex = DigestUtils.md5Hex(fis);

        // 关闭流
        fis.close();

        // 验证
        assertEquals(md5hex, "5a077abefee447cbb271e2aa7f6d5a47");
    }

}

SHA算法的使用

SHA算法,由美国国家安全局(NSA)设计,基于MD4算法基础演变而来,摘要的长度更长,安全性更高。

基于MD/SHA算法的消息传递

SHA家族共有SHA-1、SHA-224、SHA-256、SHA-384和SHA-512五种算法。Sun提供了SHA-1、SHA-256、SHA-384和SHA-512四种,且缺少对应的进制转换实现;Bouncy Castle提供了对SHA-224的支持;Commons Codec则是Sun的一个包装。后两者都支持多种形式的参数,支持十六进制字符串形式的摘要信息。

算法 摘要长度 备注
SHA-1 160 JAVA
SHA-256 256 JAVA
SHA-384 384 JAVA
SHA-512 512 JAVA
SHA-224 224 BC
import java.security.MessageDigest;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import org.apache.commons.codec.digest.DigestUtils;

public abstract class SHACoder {

    /**
     * SHA加密
     * 
     * @param data 待加密数据
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeSHA(String data) throws Exception {

        // 执行消息摘要
        return DigestUtils.sha(data);
    }

    /**
     * SHAHex加密
     * 
     * @param data 待加密数据
     * @return String 消息摘要
     * @throws Exception
     */
    public static String encodeSHAHex(String data) throws Exception {

        // 执行消息摘要
        return DigestUtils.shaHex(data);
    }

    /**
     * SHA-224加密
     * 
     * @param data
     *            待加密数据
     * @return byte[] 消息摘要
     * 
     * @throws Exception
     */
    public static byte[] encodeSHA224(byte[] data) throws Exception {
        // 加入BouncyCastleProvider支持
        Security.addProvider(new BouncyCastleProvider());

        // 初始化MessageDigest
        MessageDigest md = MessageDigest.getInstance("SHA-224");

        // 执行消息摘要
        return md.digest(data);
    }

    /**
     * SHA-224加密
     * 
     * @param data
     *            待加密数据
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static String encodeSHA224Hex(byte[] data) throws Exception {

        // 执行消息摘要
        byte[] b = encodeSHA224(data);

        // 做十六进制编码处理
        return new String(Hex.encode(b));

    }

    /**
     * SHA256加密
     * 
     * @param data 待加密数据
     * @return byte[
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值