MD5与SHA-1简介



MD5简介

MD5Message-Digest Algorithm 5(信息-摘要算法5), 用于确保信息传输完整一致. 是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法), 将数据运算为另一固定长度值,是杂凑算法的基础原理,主流编程语言普遍已有MD5实现。MD5的前身有MD2MD3MD4

MD5算法的特点

  1. 压缩性: 任意长度的数据,算出的MD5值的长度都是固定的
  2. 容易计算: 从原数据计算出MD5值很容易
  3. 抗修改性: 对原数据进行任何改动,修改一个字节生成的MD5值区别也会很大(雪崩效果)
  4. 强抗碰撞: 已知原数据和MD5, 想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的

MD5的作用

MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一个定长的十六进制数字串).

MD5的算法原理

MD5以512位分组来处理输入的信息, 且每一分组又被划分为16个32位子分组, 经过了一系列的处理后, 算法的输出由四个32位分组组成, 将这四个32位分组级联后将生成一个128位散列值.

MD5的工具类

在java中有很多MD5实现, 其中GuavaJDK都有, 下面是一些例子

  • 利用Guava中的工具
    Hashing.md5().newHasher().putString(source, Charsets.UTF_8).hash().toString();
  • 使用JDK的工具

下面这个工具完全是通过JDK实现的, 没有使用第三方工具包

public class MD5Utils {

    /**
     * 对source按UTF_8编码进行md5签名
     *
     * @param source 待签名的原串
     * @return md5签名值((32位小写16进制字符串)
     */
    public static String encode(String source) {
        return encode(source, "UTF-8");
    }

    /**
     * 对source进行md5签名
     *
     * @param source      待签名的原串
     * @param charsetName 字符编码
     * @return md5签名值((32位小写16进制字符串)
     */
    public static String encode(String source, String charsetName) {
        String resultString = null;
        try {
            // 这里涉及SPI的相关内容
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(source.getBytes());
            resultString = byteArrayToHexString(bytes);
        } catch (Exception exception) {
            throw new RuntimeException("MD5签名失败");
        }
        return resultString;
    }

    /**
     * 字节数组转换成16进制字符串
     */
    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(2 * bytes.length);
        for (byte b : bytes) {
            sb.append(hexDigits[(b >> 4) & 0xf]).append(hexDigits[b & 0xf]);
        }
        return sb.toString();
    }

    private static final char[] hexDigits = "0123456789abcdef".toCharArray();

}

SHA1简介

SHA是美国国家安全局设计的,由美国国家标准和技术研究院发布的一系列密码散列函数。 安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息, SHA1会产生一个160位的消息摘要。

SHA1的特点

  • 不可以从消息摘要中复原信息
  • 两个不同的消息不会产生同样的消息摘要(会有10^48分之一的机率出现相同的消息摘要, 一般使用时忽略)

SHA1算法流程

对于任意长度的明文, SHA1首先对其进行分组, 使得每一组的长度为512位,然后对这些明文分组反复重复处理。

对于每个明文分组的摘要生成过程如下:

  1. 将512位的明文分组划分为16个子明文分组, 每个子明文分组为32位。
  2. 申请5个32位的链接变量,记为A、B、C、D、E。
  3. 16份子明文分组扩展为80份。
  4. 80份子明文分组进行4轮运算。
  5. 链接变量与初始链接变量进行求和运算。
  6. 链接变量作为下一个明文分组的输入重复进行以上操作。
  7. 最后,5个链接变量里面的数据就是SHA1摘要。

SHA1工具类

Guava中同样有SHA1的相关工具, 类似的还有sha256, sha512等散列工具

Hashing.sha1().newHasher().putString(source, Charsets.UTF_8).hash().toString();

MD5与SHA-1的比较

MD5SHA-1都属于哈希散列算法, 都是从MD4发展而来,它们的结构和强度等特性有很多相似之处, 他们的区别主要有下面这些:

  • 安全性: MD5摘要长度128位(16字节), SHA-1摘要长度160位(20字节)
  • 速度: SHA1的运算步骤(80步)比MD5(64步)多了16步, 而且SHA1记录单元的长度比MD5多了32位, SHA1速度大约比MD5慢了25%
  • 简易性: 两种方法都是相当的简单,在实现上不需要很复杂的程序或是大量存储空间。总体上来讲, SHA1对每一步骤的操作描述比MD5简单

相关链接