md5 订阅
MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。 展开全文
MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。
信息
别    称
摘要算法
提出者
罗纳德·李维斯特
应用学科
信息技术,计算机科学
中文名
消息摘要算法
外文名
Message Digest Algorithm MD5
提出时间
1992年
MD5发展历史
1992年8月,罗纳德·李维斯特向互联网工程任务组(IETF)提交了一份重要文件,描述了这种算法的原理。由于这种算法的公开性和安全性,在90年代被广泛使用在各种程序语言中,用以确保资料传递无误等 [1]  。MD5由MD4、MD3、MD2改进而来,主要增强算法复杂度和不可逆性。MD5算法因其普遍、稳定、快速的特点,仍广泛应用于普通数据的加密保护领域 [2]  。Rivest在1989年开发出MD2算法 [3]  。在这个算法中,首先对信息进行数据补位,使信息的字节长度是16的倍数。然后,以一个16位的校验和追加到信息末尾,并且根据这个新产生的信息计算出散列值。后来,Rogier和Chauvaud发现如果忽略了校验和MD2将产生冲突。MD2算法加密后结果是唯一的(即不同信息加密后的结果不同) [4]  。为了加强算法的安全性,Rivest在1990年又开发出MD4算法 [3]  。MD4算法同样需要填补信息以确保信息的比特位长度减去448后能被512整除(信息比特位长度mod 512 = 448)。然后,一个以64位二进制表示的信息的最初长度被添加进来。信息被处理成512位damgard/merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。Den boer和Bosselaers以及其他人很快的发现了攻击MD4版本中第一步和第三步的漏洞。Dobbertin向大家演示了如何利用一部普通的个人电脑在几分钟内找到MD4完整版本中的冲突(这个冲突实际上是一种漏洞,它将导致对不同的内容进行加密却可能得到相同的加密后结果) [5]  。1991年,Rivest开发出技术上更为趋近成熟的MD5算法。它在MD4的基础上增加了"安全带"(safety-belts)的概念。虽然MD5比MD4复杂度大一些,但却更为安全。这个算法很明显的由四个和MD4设计有少许不同的步骤组成。在MD5算法中,信息-摘要的大小和填充的必要条件与MD4完全相同。Den boer和Bosselaers曾发现MD5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了 [3]  。
收起全文
精华内容
下载资源
问答
  • MD5

    万次阅读 2017-12-13 10:35:53
    一、MD5介绍 MD5MD5消息摘要算法的简称(英语:MD5 Message-Digest Algorithm),是一种广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(即哈希值),用于确保信息传输的完整性。MD5由罗纳德·...

    一、MD5介绍

    MD5是MD5消息摘要算法的简称(英语:MD5 Message-Digest Algorithm),是一种广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(即哈希值),用于确保信息传输的完整性。MD5由罗纳德·李维斯特设计,于1992年公开,用以取代MD4算法。这套算法的程序在RFC 1321 中被加以规范。
    将数据(如一段文字)运算变为另一固定长度值,是散列算法的基础原理。
    MD5已经被证实可以被碰撞破解。对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。

    CMD5上可以根据MD5密文查询出对应明文。

    二、C++生成MD5

    libmd5是计算md5值的C++开源库。这里对libmd5进行二次封装,方便调用,支持生成字符串、文件的MD5值。调用GetStringMd5生成字符串MD5;调用GetFileMd5生成文件MD5值,文件大小不受限制,但是文件越大,生成md5的耗时就越长。

    Md5Maker.h

    #ifndef __MD5_MAKER_34DFDR7_H__
    #define __MD5_MAKER_34DFDR7_H__
    
    
    #include <string>
    
    namespace cpp4j
    {
        namespace libmd5
        {
            #define UWORD32 unsigned int
            #define md5byte unsigned char
    
            struct MD5Context {
                UWORD32 buf[4];
                UWORD32 bytes[2];
                UWORD32 in[16];
            };
    
            void MD5Init(struct MD5Context *context);
            void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
            void MD5Final(unsigned char digest[16], struct MD5Context *context);
            void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16]);
            void MD5SigToString(unsigned char sig[16],char *str,int len);
        }
    
        std::string GetStringMd5(const std::string &str);
        std::string GetStringMd5(const void *pData, unsigned int iDataSize);
        std::string GetFileMd5(const std::string &strFilePath);
    }
    
    #endif

    Md5Maker.cpp

    #include "Md5Maker.h"
    
    namespace cpp4j
    {
        namespace libmd5
        {
            /*
            * This code implements the MD5 message-digest algorithm.
            * The algorithm is due to Ron Rivest.  This code was
            * written by Colin Plumb in 1993, no copyright is claimed.
            * This code is in the public domain; do with it what you wish.
            *
            * Equivalent code is available from RSA Data Security, Inc.
            * This code has been tested against that, and is equivalent,
            * except that you don't need to include two pages of legalese
            * with every copy.
            *
            * To compute the message digest of a chunk of bytes, declare an
            * MD5Context structure, pass it to MD5Init, call MD5Update as
            * needed on buffers full of bytes, and then call MD5Final, which
            * will fill a supplied 16-byte array with the digest.
            *
            * Changed so as no longer to depend on Colin Plumb's `usual.h' header
            * definitions; now uses stuff from dpkg's config.h.
            *  - Ian Jackson <ian@chiark.greenend.org.uk>.
            * Still in the public domain.
            */
    
    #define HEX_STRING      "0123456789abcdef"      /* to convert to hex */
    
            int g_bigEndian = 0;
            int g_endianessDetected = 0;
    
            void detectEndianess()
            {
                int nl = 0x12345678;
                short ns = 0x1234;
    
                unsigned char *p = (unsigned char *)(&nl);
                unsigned char *sp = (unsigned char *)(&ns);
    
                if (g_endianessDetected) return;
    
                if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
                {
                    g_bigEndian = 1;
                }
                else if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
                {
                    g_bigEndian = 0;
                }
                else
                {
                    g_bigEndian = *sp != 0x12;
                }
    
                g_endianessDetected = 1;
            }
    
            void byteSwap(UWORD32 *buf, unsigned words)
            {
                md5byte *p;
    
                if (!g_bigEndian) return;
    
                p = (md5byte *)buf;
    
                do
                {
                    *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
                             ((unsigned)p[1] << 8 | p[0]);
                    p += 4;
                }
                while (--words);
            }
    
    #ifndef ASM_MD5
    
            /* The four core functions - F1 is optimized somewhat */
    
            /* #define F1(x, y, z) (x & y | ~x & z) */
    #define F1(x, y, z) (z ^ (x & (y ^ z)))
    #define F2(x, y, z) F1(z, x, y)
    #define F3(x, y, z) (x ^ y ^ z)
    #define F4(x, y, z) (y ^ (x | ~z))
    
            /* This is the central step in the MD5 algorithm. */
    #define MD5STEP(f,w,x,y,z,in,s) \
        (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
    
            /*
             * The core of the MD5 algorithm, this alters an existing MD5 hash to
             * reflect the addition of 16 longwords of new data.  MD5Update blocks
             * the data and converts bytes into longwords for this routine.
             */
            void MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
            {
                register UWORD32 a, b, c, d;
    
                a = buf[0];
                b = buf[1];
                c = buf[2];
                d = buf[3];
    
                MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
                MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
                MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
                MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
                MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
                MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
                MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
                MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
                MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
                MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
                MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
                MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
                MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
                MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
                MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
                MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
    
                MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
                MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
                MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
                MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
                MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
                MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
                MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
                MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
                MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
                MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
                MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
                MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
                MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
                MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
                MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
                MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
    
                MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
                MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
                MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
                MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
                MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
                MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
                MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
                MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
                MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
                MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
                MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
                MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
                MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
                MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
                MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
                MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
    
                MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
                MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
                MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
                MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
                MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
                MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
                MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
                MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
                MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
                MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
                MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
                MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
                MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
                MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
                MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
                MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
    
                buf[0] += a;
                buf[1] += b;
                buf[2] += c;
                buf[3] += d;
            }
    
    #endif
    
            /*
             * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
             * initialization constants.
             */
            void MD5Init(struct MD5Context *ctx)
            {
                detectEndianess();
    
                ctx->buf[0] = 0x67452301;
                ctx->buf[1] = 0xefcdab89;
                ctx->buf[2] = 0x98badcfe;
                ctx->buf[3] = 0x10325476;
    
                ctx->bytes[0] = 0;
                ctx->bytes[1] = 0;
            }
    
            /*
             * Update context to reflect the concatenation of another buffer full
             * of bytes.
             */
            void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
            {
                UWORD32 t;
    
                /* Update byte count */
    
                t = ctx->bytes[0];
    
                if ((ctx->bytes[0] = t + len) < t)
                    ctx->bytes[1]++;    /* Carry from low to high */
    
                t = 64 - (t & 0x3f);    /* Space available in ctx->in (at least 1) */
    
                if (t > len)
                {
                    memcpy((md5byte *)ctx->in + 64 - t, buf, len);
                    return;
                }
    
                /* First chunk is an odd size */
                memcpy((md5byte *)ctx->in + 64 - t, buf, t);
                byteSwap(ctx->in, 16);
                MD5Transform(ctx->buf, ctx->in);
                buf += t;
                len -= t;
    
                /* Process data in 64-byte chunks */
                while (len >= 64)
                {
                    memcpy(ctx->in, buf, 64);
                    byteSwap(ctx->in, 16);
                    MD5Transform(ctx->buf, ctx->in);
                    buf += 64;
                    len -= 64;
                }
    
                /* Handle any remaining bytes of data. */
                memcpy(ctx->in, buf, len);
            }
    
            /*
             * Final wrapup - pad to 64-byte boundary with the bit pattern
             * 1 0* (64-bit count of bits processed, MSB-first)
             */
            void MD5Final(md5byte digest[16], struct MD5Context *ctx)
            {
                int count = ctx->bytes[0] & 0x3f;   /* Number of bytes in ctx->in */
                md5byte *p = (md5byte *)ctx->in + count;
    
                /* Set the first char of padding to 0x80.  There is always room. */
                *p++ = 0x80;
    
                /* Bytes of padding needed to make 56 bytes (-8..55) */
                count = 56 - 1 - count;
    
                if (count < 0)      /* Padding forces an extra block */
                {
                    memset(p, 0, count + 8);
                    byteSwap(ctx->in, 16);
                    MD5Transform(ctx->buf, ctx->in);
                    p = (md5byte *)ctx->in;
                    count = 56;
                }
    
                memset(p, 0, count);
                byteSwap(ctx->in, 14);
    
                /* Append length in bits and transform */
                ctx->in[14] = ctx->bytes[0] << 3;
                ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
                MD5Transform(ctx->buf, ctx->in);
    
                byteSwap(ctx->buf, 4);
                memcpy(digest, ctx->buf, 16);
                memset(ctx, 0, sizeof(*ctx));   /* In case it's sensitive */
            }
    
            void MD5Buffer (const unsigned char *buf, unsigned int len, unsigned char sig[16])
            {
                struct MD5Context md5;
                MD5Init(&md5);
                MD5Update(&md5, buf, len);
                MD5Final(sig, &md5);
            }
    
            void MD5SigToString(unsigned char signature[16], char *str, int len)
            {
                unsigned char *sig_p;
                char          *str_p, *max_p;
                unsigned int  high, low;
    
                str_p = str;
                max_p = str + len;
    
                for (sig_p = (unsigned char *)signature;
                        sig_p < (unsigned char *)signature + 16;
                        sig_p++)
                {
                    high = *sig_p / 16;
                    low = *sig_p % 16;
    
                    /* account for 2 chars */
                    if (str_p + 1 >= max_p)
                    {
                        break;
                    }
    
                    *str_p++ = HEX_STRING[high];
                    *str_p++ = HEX_STRING[low];
                }
    
                /* account for 2 chars */
                if (str_p < max_p)
                {
                    *str_p++ = '\0';
                }
            }
        }
    
        std::string GetStringMd5(const std::string &str)
        {
            unsigned char md5Sig[16] = {0};
            char szMd5[33] = {0};
    
            libmd5::MD5Buffer((const unsigned char *)str.c_str(), str.length(), md5Sig);
            libmd5::MD5SigToString(md5Sig, szMd5, 33);
    
            return szMd5;
        }
    
        std::string GetStringMd5(const void *pData, unsigned int iDataSize)
        {
            unsigned char md5Sig[16] = {0};
            char szMd5[33] = {0};
    
            libmd5::MD5Buffer((const unsigned char *)pData, iDataSize, md5Sig);
            libmd5::MD5SigToString(md5Sig, szMd5, 33);
    
            return szMd5;
        }
    
        std::string GetFileMd5(const std::string &strFilePath)
        {
            FILE *f = NULL;
    
            if(fopen_s(&f, strFilePath.c_str(), "rb"))
                return "";
    
            unsigned char szMd5Sig[16] = {0};
            char szMd5[33] = {0};
            libmd5::MD5Context md5Context;
            libmd5::MD5Init(&md5Context);
    
            size_t dwReadBytes = 0;
            unsigned char szData[1024] = {0};
    
            while((dwReadBytes = fread(szData, 1, 1024, f)) > 0)
            {
                libmd5::MD5Update(&md5Context, szData, dwReadBytes);
            }
    
            fclose(f);
    
            libmd5::MD5Final(szMd5Sig, &md5Context);
            libmd5::MD5SigToString(szMd5Sig, szMd5, 33);
    
            return szMd5;
        }
    }

    参考:https://zh.wikipedia.org/wiki/MD5

    展开全文
  • md5

    千次阅读 2015-03-30 11:09:47
    php中md5函数与linux中md5sum结果不同的问题  2014-05-05 11:04:40| 分类: 技术...简而言之,linux中用echo “123”| md5sum或md5sum 文件名方式来计算某串的md5值,串中都有隐含的字符串\0终止符或换行符的存在

    摘要:(1)任何工具语言md5的结果是一样的



    php中md5函数与linux中md5sum结果不同的问题  

    2014-05-05 11:04:40|  分类: 技术相关 |  标签:php  linux  md5  md5sum  |举报|字号 订阅

    简而言之,linux中用echo “123”| md5sum或md5sum 文件名方式来计算某串的md5值,串中都有隐含的字符串\0终止符或换行符的存在,所以并非只计算了"123”的md5值。大可不必怀疑md5算法。用echo –n “123”|md5sum即可得出与php中md5函数相同的结果。


    转自:http://blog.163.com/squall_smile/blog/static/6034984020144511440176/

    展开全文
  • MD5算法如何被破解

    万次阅读 多人点赞 2018-04-02 20:55:29
    小明:老师,上次您讲了MD5算法。用它生成的信息摘要,真的可以被破解吗? 老师:有很多种方法可以破解,不过需要明确一点,这里所谓的破解,并非把摘要还原成原文。为什么呢?因为固定128位的摘要是有穷的,而原文...

    个人博客请访问 http://www.x0100.top  

    小明:老师,上次您讲了MD5算法。用它生成的信息摘要,真的可以被破解吗?

    老师:有很多种方法可以破解,不过需要明确一点,这里所谓的破解,并非把摘要还原成原文。为什么呢?因为固定128位的摘要是有穷的,而原文数量是无穷的,每一个摘要都可以由若干个原文通过Hash得到。

    小明:如果是这样的话,网上所说的MD5破解到底是怎么回事呢?

    老师:对于MD5的破解,实际上都属于【碰撞】。比如原文A通过MD5可以生成摘要M,我们并不需要把X还原成A,只需要找到原文B,生成同样的摘要M即可。

    设MD5的哈希函数是H(X),那么:

    H(A) = M

    H(B) = M

    任意一个B即为破解结果。

    B有可能等于A,也可能不等于A。

    用一个形象的说法,A和B的MD5结果“殊途同归”。

    MD5碰撞通常用于登陆密码的破解。应用系统的数据库中存储的用户密码通常都是原密码的MD5哈希值,每当用户登录时,验签过程如下:

    如果我们得到了用户ABC的密码哈希值E10ADC3949BA59ABBE56E057F20F883E,并不需要还原出原密码123456,只需要“碰撞”出另一个原文654321(只是举例)即可。登录时,完全可以使用654321作为登陆密码,欺骗过应用系统的验签。

    小明:那么,具体如何来实现MD5摘要的碰撞呢?

    老师:MD5碰撞的方法有很多,主要包括暴力枚举法、字典法、彩虹表法等等。

    暴力枚举法:

    老师:暴力枚举法顾名思义,就是简单粗暴地枚举出所有原文,并计算出它们的哈希值,看看哪个哈希值和给定的信息摘要一致。这种方法虽然简单,但是时间复杂度极高。想象一下,仅仅长度8位的密码就有多少种排列组合的可能性?

    小明:只考虑大小写字母和数字,每一位有62种可能,那么8位密码的排列组合就是62的8次方,218340105584800,约等于二百万亿!

    老师:是的,这样的数据量如果使用普通的单机来破解,恐怕头发白了也破解不完。不过,我们也可以做一些取巧,优先尝试生日和有意义的单词,这样就可以把穷举范围缩小很多。

    字典法:

    老师:如果说暴力枚举法是ongoing时间换空间,那么字典法则是用空间换时间。黑客利用一个巨大的字典,存储尽可能多的原文和对应的哈希值。每次用给定的信息摘要查找字典,即可快速找到碰撞的结果。

    不过,这样做虽然每次破解速度很快,但是生成字典需要巨大的空间。仍然以8位密码举例,需要多大空间呢?

    小明:刚才计算过有218340105584800种可能性,每一对映射占192(128+64)bit。那么大约需要4.65PB的存储空间。

    老师:没错,这样做的存储成本实在太大了。当然,我们同样可以取巧,优先存储那些常用的密码及其摘要。

    小明:那么,有没有什么方法可以做到时间和空间的均衡呢?

    老师:有一种方法可以,那就是下面我要介绍的【彩虹表发】。

    彩虹表法:

    老师:彩虹表法可以说是对字典法的优化,它采用了一种有趣的数据结构:【彩虹表】。在学习彩虹表之前,我们先来了解两个基本函数:H(X)和R(X)。

    H(X):生成信息摘要的哈希函数,比如MD5,比如SHA256。

    R(X):从信息摘要转换成另一个字符串的衰减函数(Reduce)。其中R(X)的定义域是H(X)的值域,R(X)的值域是H(X)的定义域。但要注意的是,R(X)并非H(X)的反函数。

    通过交替运算H和R若干次,可以形成一个原文和哈希值的链条。假设原文是aaaaaa,哈希值长度32bit,那么哈希链表就是下面的样子:

    这个链条有多长呢?假设H(X)和R(X)的交替重复K次,那么链条长度就是2K+1。同时,我们只需把链表的首段和末端存入哈希表中:

    小明:这什么跟什么啊,衰减函数和哈希链条,到底是干什么用的?

    老师:别急,我们来演示一次破解过程,你就明白它们的意义了。

    给定信息摘要:920ECF10

    如何得到原文呢?只需进行R(X)运算:

    R(920ECF10)= kiebgt

    查询哈希表可以找到末端kiebgt对应的首端是aaaaaa,因此摘要920ECF10的原文“极有可能”在aaaaaa到kiebgt的这个链条当中。

    接下来从aaaaaa开始,重新交替运算R(X)与H(X),看一看摘要值920ECF10是否是其中一次H(X)的结果。从链条看来,答案是肯定的,因此920ECF10的原文就是920ECF10的前置节点sgfnyd。

    需要补充的是,如果给定的摘要值经过一次R(X)运算,结果在哈希表中找不到,可以继续交替H(X)R(X)直到第K次为止。

    简单来说,哈希链表代表了一组映射关系,其中每组包含K对映射,但只需要存储链条首位两个字符串。假设K=10,那么存储空间只有全量字典的十分之一,代价则是破解一个摘要的运算次数也提高了十倍。这就是时间和空间的取舍。虽然做了取舍,但是哈希链条存在一个致命的缺陷:R(X)函数的可靠性。虽然我们尽量把R(X)设计成结果均匀分布的函数,但是再完美的函数也难免会有碰撞的情况,比如下面这样:

    给定信息摘要:FB107E70

    经过多次R(X),H(X)运算,得到结果kiebgt

    通过哈希表查找末端kiebgt,可以找出首端aaaaaa

    但是,FB107E70并不在aaaaaa到kiebgt的哈希链条当中,这就是R(X)的碰撞造成的。

    这个问题看似没什么影响,既然找不到就重新生成一组首尾映射即可。但是想象一下,当K值较大的时候,哈希链很长,一旦两条不同的哈希链在某个节点出现碰撞,后面所有的明文和哈希值全都变成了一毛一样的值。

    这样造成的后果就是冗余存储。原本两条哈希链可以存储 2K个映射,由于重复,真正存储的映射数量不足2K。

    这个时候,我们设计了彩虹表。彩虹表对哈希链进行了改进,把原先的R(X)的函数改进成从R1(X)到Rk(X)一共K个衰减函数。这样一来虽然也可能发生碰撞,但是碰撞只会发生在同一级运算,如R1和R1碰撞,R3和R3碰撞,大大减小了存储重复的几率。

    小明:好复杂,听的头都晕了。那想要破解MD5算法,有没有比彩虹表更厉害的方法呢?

    老师:还真有。

    2004年,王小云教授提出了非常高效的MD5碰撞方法。

    2009年,冯登国、谢涛利用差分攻击,将MD5的碰撞算法复杂度进一步降低。

    有兴趣的小伙伴可以通过资料进行更深入的学习。

    几点补充:

    对于单机来说,暴力枚举法的时间成本很高,字典法的空间成本很高。但是利用分布式计算和分布式存储,仍然可以有效破解MD5算法。因此这两种方法同样被黑客们广泛使用。

    关注微信公众号和今日头条,精彩文章持续更新中。。。。。

     

    展开全文
  • java将字符串进行MD5加密

    万次阅读 热门讨论 2017-12-09 15:06:14
    对于一个明文,为了安全,有时我们需要对其进行MD5加密,下面提供2个java工具方法,直接调用其中一个即可。 方法1: /** * MD5加密 */ public class MD5Util { /** * Encodes a string 2 MD5 * * @param ...

    对于一个明文,为了安全,有时我们需要对其进行MD5加密,下面提供1个java工具方法,直接调用即可。

     

     

    /**
     * MD5加密
     */
    public class MD5Util {
    
    	/**
    	 * Encodes a string 2 MD5
    	 * 
    	 * @param str String to encode
    	 * @return Encoded String
    	 * @throws NoSuchAlgorithmException
    	 */
    	public static String crypt(String str) {
    		if (str == null || str.length() == 0) {
    			throw new IllegalArgumentException("String to encript cannot be null or zero length");
    		}
    		StringBuffer hexString = new StringBuffer();
    		try {
    			MessageDigest md = MessageDigest.getInstance("MD5");
    			md.update(str.getBytes());
    			byte[] hash = md.digest();
    			for (int i = 0; i < hash.length; i++) {
    				if ((0xff & hash[i]) < 0x10) {
    					hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
    				} else {
    					hexString.append(Integer.toHexString(0xFF & hash[i]));
    				}
    			}
    		} catch (NoSuchAlgorithmException e) {
    			e.printStackTrace();
    		}
    		return hexString.toString();
    	}
    
    }
    

    欢迎关注微信公众号(Java修炼记):

    专注Java技术积累,免费分享Java技术干货、学习笔记、学习资料等,致力于让这里成为一个java知识小站。

     

     

     

     

     

     

     

     

     

     

    展开全文
  • js md5加密 无法md5解密

    万次阅读 2018-08-21 11:41:48
    微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 在util目录添加md5.js文件 : 下载地址:https://download.csdn.net/download/qq_35713752/10617174;...var MD5Encode = require(...
  • md5MD5SUM

    千次阅读 2016-01-25 20:43:43
    好久没有写博客了,居然忘了md5md5sum的区别 我们默认算出的md5是不包含\0或者换行的,而md5sum包含。 建议大家试一下 echo -n abcd | md5sum 
  • MD5.js,前端MD5加密

    万次阅读 2017-10-26 11:23:29
    MD5.js 共有6中加密方法:hex_md5(s), b64_md5(s) ,str_md5(s) ,hex_hmac_md5(key, data), b64_hmac_md5(key, data) ,str_hmac_md5(key, data).根据需求选择. js加密的好处: 1,用js对私密信息加密可避免在网络中...
  • 可以通过Browse选择要检测的文件,越大的文件需要的检测时间就越长,静静等待一会后就会展示出被测文件的MD5等信息,然后对比下载文件的网站给出的该文件正确的MD5值,如果一样的话就说明文件是完整的。 SHA1和CRC...
  • MD5介绍与MD5加密的C++实现

    千次阅读 2018-07-15 11:35:40
    MD5相信绝大数人都接触过,也有无数人问过我怎么做MD5解密。 当然,我们知道MD5自然没有办法解密,所以解密也不过是大量已知数据做成字典而已,MD5是不可能通过逆向计算解密的。 为什么呢?因为哈希冲突。 举个...
  • JAVA MD5转JS MD5加密

    2017-10-27 03:20:52
    public class md5 { public static String getMd5(String plainText) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(plainText.getBytes()); byte b[] = md.digest(); ...
  • md5 collision(md5碰撞)

    千次阅读 2019-07-24 14:12:21
    题目来源:南京邮电大学网络攻防训练平台 Web题 md5 collision 解题过程: 点开题目标题,呈现在眼前的是一段php代码,代码如下: $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){...
  • python md5

    千次阅读 2019-06-18 19:15:02
    def md5value(s): md5 = hashlib.md5() md5.update(s.encode("utf8")) return md5.hexdigest()
  • C# 获取MD5 (MD5计算,MD5小工具)

    千次阅读 2016-11-12 14:46:53
    拖拽文件或文件夹至getMD5.exe上,可自动计算文件或文件夹下所有文件的MD5值,保存至文件MD5.txt中 方式三: 通过cmd命令调用(类似方式二) REM 获取1.txt和files目录下所有文件的MD5值 getMD5.exe &...
  • MD5加密 生成32位md5

    千次阅读 2018-08-30 14:16:29
    MD5加密 生成32位md5码 工具类: import java.security.MessageDigest; public class MD5Util { /*** * MD5加密 生成32位md5码 * @param 待加密字符串 * @return 返回32位md5码 */ public static String...
  • MD5Init-MD5Update-MD5Final

    万次阅读 2014-04-10 10:55:32
    MD5Init是一个初始化函数,初始化核心变量,装入标准的幻数 MD5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个函数由getMD5ofStr调用,调用之前需要调用md5init MD5Final整理和填写输出...
  • Java生成MD5的两种方式

    万次阅读 多人点赞 2018-06-28 12:56:11
    1 原生的 package ... import java.security.MessageDigest; /** * MD5加密工具类 * @author pibigstar * */ public class MyMD5Util { //盐,用于混交md5 private static final String sl...
  • MD5算法原理与实现

    万次阅读 多人点赞 2014-07-17 21:03:52
    一、MD5概念 MD5,全名Message Digest Algorithm 5 ,中文名为消息摘要算法第五版,为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。上面这段话话引用自百度百科,我的理解MD5是一种信息摘要...
  • MD5算法详解

    万次阅读 多人点赞 2018-07-16 17:30:26
    MD5是一种哈希算法,用来保证信息的完整性。 就一段信息对应一个哈希值,且不能通过哈希值推出这段信息,而且还需要保证不存在任意两段不相同的信息对应同一个哈希值。不过MD5算法算出来的值也就16个字节(16*8=...
  • MD5加密工具类MD5Utils

    千次阅读 2018-09-01 02:23:50
    1.使用自定义工具类MD5Utils package com.utils; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Utils { public static ...
  • md5加密

    千次阅读 2018-12-27 17:22:47
    MD5 加密 使用qmd5必须先引入jquery!!! var md5Value=hex_md5(&quot;需要被加密的字符串&quot;); alert(&quot;加密后的值为:&quot;+md5Value); qmd5 下载引入地址

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 107,816
精华内容 43,126
关键字:

md5