as3corelib 的 MD5.digest.endian 应该是 LITTLE_ENDIAN

标签: as3corelib md5 digest | 发表时间:2011-09-27 02:35 | 作者:lanphaday 非狐外传
出处:http://blog.csdn.net/lanphaday
赖勇浩(http://laiyonghao.com

MD5.digest 简介

MD5 算法(http://en.wikipedia.org/wiki/MD5)已经是使用最为广泛的信息摘要算法之一,常用以错误检查,比如命令 md5sum。
$ md5sum protobuf-2.4.1.tar.gz
dc84e9912ea768baa1976cb7bbcea7b5  protobuf-2.4.1.tar.gz
当我们通过网络传输 protobuf-2.4.1.tar.gz 后,可以在另一端通过比对它的 md5sum 结果是否相同来进行校验。
如上我们可以看到 md5sum 的结果是 32 个字符的字符串,每个字符是一个 16 进制数,一般称之为 hexdigest。除了这种形式,md5 值还可以使用 16 字节的二进制序列来表示,称之为 digest。显然后者在空间上更有优势,所以有时候存储、网络传输 md5 值的时候,我们会选择使用 digest。
根据 MD5 算法的 RFC(http://tools.ietf.org/html/rfc1321),我们可以知道其实 digest 就是 4 个连续存储的 4 字节的整型。我们也知道不同的平台上,有不同的字节序(http://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F),所以 RFC1321 在它的“APPENDIX A - Reference Implementation”里编写了 Encode/Decode 函数,指明 md5.digest 应该使用 LITTLE_ENDIAN。
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
  a multiple of 4.
 */
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
  unsigned int i, j;

  for (i = 0, j = 0; j < len; i++, j += 4) {
 output[j] = (unsigned char)(input[i] & 0xff);
 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
  }
}

/* Decodes input (unsigned char) into output (UINT4). Assumes len is
  a multiple of 4.
 */
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
  unsigned int i, j;

  for (i = 0, j = 0; j < len; i++, j += 4)
 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
而上文提到的 md5 wikipedia 页面也有一行代码注释提到应为小端序:
var char digest[16] := h0 append h1 append h2 append h3 //(expressed as little-endian)

as3corelib 的问题

在 as3corelib 中,MD5.digest 是一个 ByteArray 实例,见 https://github.com/mikechambers/as3corelib/blob/master/src/com/adobe/crypto/MD5.as#L42 。ByteArray 实现了 IDataInput 和 IDataOutput 接口,自然也像其它实现了这两个接口的 FileStream, Socket 类一样继承了 endian 属性,其默认值是 BIG_ENDIAN。在 as3corelib 的当前实现中,digest 使用的是默认的 BIG_ENDIAN,见 https://github.com/mikechambers/as3corelib/blob/master/src/com/adobe/crypto/MD5.as#L182,或如下代码:
digest = new ByteArray()
digest.writeInt(a);
digest.writeInt(b);
digest.writeInt(c);
digest.writeInt(d);
digest.position = 0;
当传输 digest 到另一个进程进行比对时,就会发现 md5 检验和不匹配的情况了。

解决方案

最根本的方案应该是给 as3corelib 打个 patch,修正这个 bug,使之实现符合 RFC,附 patch 如下:
---
 src/com/adobe/crypto/MD5.as |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/src/com/adobe/crypto/MD5.as b/src/com/adobe/crypto/MD5.as
index da533cc..db5406a 100644
--- a/src/com/adobe/crypto/MD5.as
+++ b/src/com/adobe/crypto/MD5.as
@@ -34,6 +34,7 @@ package com.adobe.crypto {

        import com.adobe.utils.IntUtil;
        import flash.utils.ByteArray;
+       import flash.utils.Endian;
        /**
         * The MD5 Message-Digest Algorithm
         *
@@ -178,7 +179,8 @@ package com.adobe.crypto {
                                c += cc;
                                d += dd;
                        }
-                       digest = new ByteArray()
+                       digest = new ByteArray();
+                       digest.endian = Endian.LITTLE_ENDIAN;
                        digest.writeInt(a);
                        digest.writeInt(b);
                        digest.writeInt(c);
-- 
1.7.0.4
我已经向 as3corelib 的维护者反映这个问题,估计不日就可以由官方修复。但在官方发布新版本之前,我们也可以选择两个变通方案,一是使用 hexdigest,二是编写一个自己的转换函数 toLittleEndianMd5Digest,把 MD5.digest 转为 LITTLE_ENDIAN,实现如下:
            function toLittleEndianMd5Digest(ba:ByteArray):ByteArray
            {
                if(ba.endian == Endian.LITTLE_ENDIAN)
                {
                    return ba;
                }
                var new_ba:ByteArray = new ByteArray();
                new_ba.endian = Endian.LITTLE_ENDIAN;
                new_ba.writeInt(ba.readInt());
                new_ba.writeInt(ba.readInt());
                new_ba.writeInt(ba.readInt());
                new_ba.writeInt(ba.readInt());
                new_ba.position = 0;
                return new_ba;
            }
... // 省略业务代码
// 在用到 MD5.digest 的地方
var md5:ByteArray = toLittleEndianMd5Digest(MD5.digest);
这个 toLittleEndianMd5Digest 函数能够在 as3corelib 修正这个 bug 以后保持兼容,所以不用担心后遗症,可以放心大胆地使用。

作者:lanphaday 发表于2011-9-26 11:35:14 原文链接
阅读:230 评论:0 查看评论

相关 [as3corelib md5 digest] 推荐:

as3corelib 的 MD5.digest.endian 应该是 LITTLE_ENDIAN

- 非狐外传 - 赖勇浩的编程私伙局
赖勇浩(http://laiyonghao.com). MD5 算法(http://en.wikipedia.org/wiki/MD5)已经是使用最为广泛的信息摘要算法之一,常用以错误检查,比如命令 md5sum. 当我们通过网络传输 protobuf-2.4.1.tar.gz 后,可以在另一端通过比对它的 md5sum 结果是否相同来进行校验.

Apache Tomcat DIGEST身份验证多个安全漏洞(CVE-2012-3439)

- - C1G军火库
发布时间: 2012-11-05 (GMT+0800). Apache Tomcat是一个流行的开放源码的JSP应用服务器程序. Apache Tomcat 7.0.0-7.0.27、6.0.0-6.0.35、5.5.0-5.5.35存在多个安全漏洞,成功利用后可允许攻击者绕过安全限制并执行非法操作.

pt-query-digest查询日志分析工具

- - 数据库 - ITeye博客
pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog、General log、slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump抓取的MySQL协议数据来进行分析. 可以把分析结果输出到文件中,分析过程是先对查询语句的条件进行参数化,然后对参数化以后的查询进行分组统计,统计出各查询的执行时间、次数、占比等,可以借助分析结果找出问题进行优化.

学用MD5检查文件内容是否一致

- Penny - 效率天阶
面对同一个文件的N个版本以及N个副本,你是否能很快地挑出其中内容相同的那些. 如果你的答案是NO(或者:我可以一个个打开看),那就来跟效率天阶一起,学学怎么用MD5检查文件内容是否一致吧....

国外hash(MD5、NTLM、LM、SHA)密码在线破解网站

- - 服务器运维与网站架构|Linux运维|X研究
PS:这是国外的hash密码在线破解网站列表,支持多种类型的hash密码,目前可查询破解的hash包括:MD5、NTLM、LM、SHA1、SHA 256-512、MySQL、WPA-PSK.

MD5加密及第三方支付接口的技术比较

- - 企业架构 - ITeye博客
摘  要:第三方支付市场的发展前景乐观,但同时市场竞争也越来越激烈. 随着第三方支付业务许可牌照的发放,第三方支付将很可能打破大型银行垄断电子金融的局面. 本文将主要研究第三方支付的“网上支付接口”,比较分析各种不同的第三方支付接口的差异性. 关键词:电子支付 第三方支付 支付接口. 电子支付是电子商务中重要的一个环节,其中第三方支付是电子支付的一种重要方式.

JavaWeb实现服务器端到客户端的验证码(MD5)校验

- - ITeye博客
首先看看服务端产生验证码的代码. (很简单 A-Z, 然后是0-9). /** * 产生验证码类(MD5)加密 * @author Thunder * */ public class VerificationCode {. * @param codeLength 指定验证码的长度. * @return 随机生成的验证码.

[Mac新手必备,不收藏悔死你,7.27更新]MacOS系统常用软件下载,持续更新,全部配图+MD5

- HICU - FeedzShare
来自: bbs.weiphone.com - FeedzShare  . 发布时间:2011年08月07日,  已有 2 人推荐. 很多网友说下载回去的东西打不开,或者其他什么的,基本都是由于下载失败所致,115网盘目前无法支持使用folx或者speed download等工具下载,所以只能使用浏览器自带的下载,而这种下载方式又可能导致下载不完全,看似下载 ...