【字符编码系列】MD5与SHA-1

栏目: 编程工具 · 发布时间: 8年前

内容简介:【字符编码系列】MD5与SHA-1

写在前面的话

本文属于 字符编码系列文章之一,更多请前往 字符编码系列

本文中大量资料都是参考或直接复用的来源链接中的,整理本文更多的是梳理自己的知识体系,以及便于后续回顾。

TODO: 后续还需要对整个MD5以及SHA-1算法重新梳理

大纲

  • MD5简介
  • SHA-1简介
  • MD5 与SHA-1 的比较
  • MD5 与SHA-1 的算法简述
  • 源码实现

MD5简介

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法)。

主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。

MD5的特点

  • 不可逆: 不可以从消息摘要中复原信息
  • 压缩性:任意长度的数据,算出的MD5值的长度都是固定的(128 bit)
  • 抗修改性:对原数据进行任何改动,修改一个字节生成的MD5值区别也会很大
  • 强抗碰撞:已知原数据和MD5,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
  • 容易计算:从原数据计算出MD5值很容易

MD5的作用

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

MD5原理简述

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

SHA-1简介

SHA是美国国家安全局设计的,由美国国家标准和技术研究院发布的一系列密码散列函数。

最初载明的算法于1993年发布,称做安全散列标准 (Secure Hash Standard),FIPS PUB 180。这个版本常被称为 “SHA-0”。它在发布之后很快就被NSA撤回,并且以 1995年发布的修订版本 FIPS PUB 180-1 (通常称为 “SHA-1”) 取代。

SHA-1的特点

  • 不可逆: 不可以从消息摘要中复原信息
  • 压缩性:任意长度的数据,算出的SHA-1值的长度都是固定的(160 bit)
  • 抗修改性:对原数据进行任何改动,修改一个字节生成的SHA-1值区别也会很大
  • 更加安全: 相比MD5,SHA-1由于摘要长度更长了,所以相比来说强行攻击SHA-1的难度更大(当然,安全都是相对而言的)
  • 计算较慢:由于SHA-1的循环步骤比MD5多80:64且要处理的缓存大160比特:128比特,SHA-1的运行速度比MD5慢

SHA-1的作用

这个安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。

对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。

SHA-1原理简述

在SHA1算法中,我们必须把原始消息(字符串,文件等)转换成位字符串。SHA1算法只接受位作为输入。假设我们对字符串“abc”产生消息摘要。首先,我们将它转换成位字符串如下:01100001 01100010 01100011 ‘a’=97 ‘b’=98 ‘c’=99 这个位字符串的长度为24

MD5 与SHA-1 的比较

由于MD5 与SHA-1均是从MD4 发展而来,它们的结构和强度等特性有很多相似之处,下表是对MD5 与SHA-1 的结构比较。

SHA-1与MD5 的最大区别在于其摘要比MD5 摘要长 32 比特。对于强行攻击,产生任何一个报文使之摘要等于给定报文摘要的难度:

  • MD5 是2128 数量级的操作
  • SHA-1 是2160 数量级的操作。

产生具有相同摘要的两个报文的难度:

  • MD5是 264 是数量级的操作
  • SHA-1 是280 数量级的操作

因而,SHA-1 对强行攻击的强度更大。但由于SHA-1 的循环步骤比MD5 多(80:64)且要处理的缓存大(160 比特:128 比特),SHA-1 的运行速度比MD5 慢。

MD5 SHA-1
分组长度 512 bit 512 bit
摘要长度 128 bit 160 bit
循环中的步骤 64 80
报文最大长度 无穷大 2^64 - 1
基本逻辑函数 4 4
结构形式 Little-endian(小端序) Big-endian(大端序)

MD5 与SHA-1 的算法简述

SHA1和MD5的算法都是从MD4算法改进而来的2种算法。

基本思路都是将信息分成N个分组,每组64个字节,每个分组都进行摘要运算。当一个分组的摘要运算完毕后,将上一个分组的结果也用于下一个分组的运算。

信息的长度(注意是bit位长度,不是字节长度)用64位表示,也要参加信息摘要运算,而且是放在最后一个分组的末尾,所以长度信息要占据8个字节。

如果信息数据最后一个分组长度小于64个字节,在后面添加0x80标志结束,如果此时数据+结束标志已经<=56个字节,还可以放入长度数据,就在结束标志到第56个字节补0,然后放入长度,如果此时信息数据+结束标志已经大于56字节,那么这个分组后面补0,进行一次摘要运算,然后再建立一个分组,前面全部补0,最后16个字节放长度,再进行一次摘要。

需要注意的地方如下。

  • MD5最后生成的摘要信息是16个字节,SHA1是20个字节。
  • MD5和SHA1的分组信息运算,分组里面的的数据都会被视为16个DWORD
  • 而MD5算法认为这些DWORD的字节序列是LITTLE-ENDIAN(小端序)
  • 而SHA1的算法认为DWORD是BIG-ENDIAN(大端序)。
  • 所以在不同字节序的主机上要进行转换。放入最后一个分组的长度信息,是原始数据长度,而且是BIT位长度。

源码实现

以下这个JS试下的SHA-1方式基本就是来源于参考链接中的。

(function(exports) {
    "use strict";
    /**
     * 决定hex是大写散列还是小写散列
     * 为true为大写
     */
    var hexcase = 0;
    var b64pad = "";
    var chrsz = 8;
    /**
     * @description hex_sha1加密,据传是最安全的散列方法,不可逆
     * @param {String} s 加密内容
     * @return {String} 返回密文,hex字符串
     */
    exports.sha1_hex = function(s) {
        return binb2hex(core_sha1(str2binb(s), s.length * chrsz))
    };
    /**
     * @description b64_sha1加密,也是sha1加密的一种,不可逆
     * @param {String} s 加密内容
     * @return {String} 返回密文,base64字符串
     */
    exports.sha1_b64 = function(s) {
        return binb2b64(core_sha1(str2binb(s), s.length * chrsz))
    };
    /**
     * @description 普通字符串加密,也是sha1加密的一种,不可逆
     * @param {String} s 加密内容
     * @return {String} 返回密文,string字符串
     */
    exports.sha1_str = function(s) {
        return binb2str(core_sha1(str2binb(s), s.length * chrsz))
    };

    function hex_hmac_sha1(key, data) {
        return binb2hex(core_hmac_sha1(key, data))
    }

    function b64_hmac_sha1(key, data) {
        return binb2b64(core_hmac_sha1(key, data))
    }

    function str_hmac_sha1(key, data) {
        return binb2str(core_hmac_sha1(key, data))
    }

    function core_sha1(x, len) {
        x[len >> 5] |= 0x80 << (24 - len % 32);
        x[((len + 64 >> 9) << 4) + 15] = len;
        var w = Array(80);
        var a = 1732584193;
        var b = -271733879;
        var c = -1732584194;
        var d = 271733878;
        var e = -1009589776;
        for(var i = 0; i < x.length; i += 16) {
            var olda = a;
            var oldb = b;
            var oldc = c;
            var oldd = d;
            var olde = e;
            for(var j = 0; j < 80; j++) {
                if(j < 16) w[j] = x[i + j];
                else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
                var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
                e = d;
                d = c;
                c = rol(b, 30);
                b = a;
                a = t
            }
            a = safe_add(a, olda);
            b = safe_add(b, oldb);
            c = safe_add(c, oldc);
            d = safe_add(d, oldd);
            e = safe_add(e, olde)
        }
        return Array(a, b, c, d, e)
    }

    function sha1_ft(t, b, c, d) {
        if(t < 20) return(b & c) | ((~b) & d);
        if(t < 40) return b ^ c ^ d;
        if(t < 60) return(b & c) | (b & d) | (c & d);
        return b ^ c ^ d
    }

    function sha1_kt(t) {
        return(t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514
    }

    function core_hmac_sha1(key, data) {
        var bkey = str2binb(key);
        if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
        var ipad = Array(16),
            opad = Array(16);
        for(var i = 0; i < 16; i++) {
            ipad[i] = bkey[i] ^ 0x36363636;
            opad[i] = bkey[i] ^ 0x5C5C5C5C
        }
        var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
        return core_sha1(opad.concat(hash), 512 + 160)
    }

    function safe_add(x, y) {
        var lsw = (x & 0xFFFF) + (y & 0xFFFF);
        var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
        return(msw << 16) | (lsw & 0xFFFF)
    }

    function rol(num, cnt) {
        return(num << cnt) | (num >>> (32 - cnt))
    }

    function str2binb(str) {
        var bin = Array();
        var mask = (1 << chrsz) - 1;
        for(var i = 0; i < str.length * chrsz; i += chrsz) bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i % 32);
        return bin
    }

    function binb2str(bin) {
        var str = "";
        var mask = (1 << chrsz) - 1;
        for(var i = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i >> 5] >>> (32 - chrsz - i % 32)) & mask);
        return str
    }

    function binb2hex(binarray) {
        var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
        var str = "";
        for(var i = 0; i < binarray.length * 4; i++) {
            str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF)
        }
        return str
    }

    function binb2b64(binarray) {
        var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        var str = "";
        for(var i = 0; i < binarray.length * 4; i += 3) {
            var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
            for(var j = 0; j < 4; j++) {
                if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
                else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F)
            }
        }
        return str
    }
    
    // 可以将exports暴露成自己的命名空间
    Util.namespace('md5', exports);

})({});

源码

详细可以参考源码: https://github.com/dailc/charset-encoding-series

附录

参考资料


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

About Face 3

About Face 3

Alan Cooper、Robert Reimann、David Cronin / John Wiley & Sons / 2007-5-15 / GBP 28.99

* The return of the authoritative bestseller includes all new content relevant to the popularization of how About Face maintains its relevance to new Web technologies such as AJAX and mobile platforms......一起来看看 《About Face 3》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具