热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

探讨PHP自定义MD5加密函数的实现问题

本文分析了一个基于ASP代码改编的PHPMD5加密函数,指出其存在的问题,并提供了解决方案。通过对比ASP和PHP在处理相同数据时的不同表现,探讨了两种语言在实现MD5算法上的细微差别。
### 分析与讨论

#### 1. 代码来源及问题概述

观察代码可以发现,这段PHP MD5加密函数显然是从ASP代码转换而来。由于两种语言在处理整数和位操作上的差异,直接移植的代码在PHP环境下运行时出现了问题。主要表现为输出结果与预期不符。

#### 2. 代码分析

- **位移操作**:PHP和ASP在处理位移操作时存在差异,特别是对于32位以上的数值。PHP中,当数值超出32位时,默认会将其转换为浮点数,这可能导致计算结果的偏差。
- **整数处理**:PHP中默认整数为有符号类型,而ASP中某些情况下可能会将高位为1的值视为负数。这种差异在处理MD5算法中的某些特定步骤时尤为明显。

#### 3. 问题解决

- **修正位移操作**:确保所有位移操作都在32位范围内进行,避免数值溢出导致的错误。
- **整数类型转换**:在必要时使用`intval()`函数将浮点数强制转换为整数,以保证与ASP中类似的操作一致性。

#### 4. 代码示例

```php
function LShift($lValue, $iShiftBits) {
if ($iShiftBits == 0) return $lValue;
if ($iShiftBits == 31) {
if ($lValue & 1) { return 0x80000000; }
else { return 0; }
}
if ($iShiftBits <0 || $iShiftBits > 31) { return 0; }
return ($lValue <<$iShiftBits) | (($lValue & 0xFFFFFFFF) >> (32 - $iShiftBits));
}

function RShift($lValue, $iShiftBits) {
if ($iShiftBits == 0) return $lValue;
if ($iShiftBits == 31) {
if ($lValue & 0x80000000) { return 1; }
else { return 0; }
}
if ($iShiftBits <0 || $iShiftBits > 31) { return 0; }
return ($lValue >> $iShiftBits) | (($lValue & 0x7FFFFFFF) <<(32 - $iShiftBits));
}

// 其他函数如 RotateLeft, AddUnsigned, md5_F, md5_G, md5_H, md5_I, md5_FF, md5_GG, md5_HH, md5_II 等保持不变

function ConvertToWordArray($sMessage) {
$lWordArray = array();
$MODULUS_BITS = 512;
$CONGRUENT_BITS = 448;
$lMessageLength = strlen($sMessage);
$lNumberOfWords = (floor(($lMessageLength + floor(($MODULUS_BITS - $CONGRUENT_BITS) / 8)) / floor($MODULUS_BITS / 8)) + 1) * floor($MODULUS_BITS / 32);
$lBytePosition = 0;
$lByteCount = 0;
while (!($lByteCount >= $lMessageLength)) {
$lWordCount = floor($lByteCount / 4);
$lBytePosition = ($lByteCount % 4) * 8;
$lWordArray[$lWordCount] = $lWordArray[$lWordCount] | LShift(ord(substr($sMessage, $lByteCount, 1)), $lBytePosition);
$lByteCount++;
}
$lWordCount = floor($lByteCount / 4);
$lBytePosition = ($lByteCount % 4) * 8;
$lWordArray[$lWordCount] = $lWordArray[$lWordCount] | LShift(0x80, $lBytePosition);
$lWordArray[$lNumberOfWords - 2] = LShift($lMessageLength, 3);
$lWordArray[$lNumberOfWords - 1] = RShift($lMessageLength, 29);
return $lWordArray;
}

function WordToHex($lValue) {
$tmpstr = '';
for ($lCount = 0; $lCount <= 3; $lCount++) {
$lByte = RShift($lValue, $lCount * 8) & 0xFF;
$tmpstr .= substr('0' . dechex($lByte), -2, 2);
}
return $tmpstr;
}

function php_MD5($sMessage) {
// 初始化全局变量
for ($i = 0; $i <= 30; $i++) {
$GLOBALS[$i] = intval(pow(2, $i));
}

$S11 = 7; $S12 = 12; $S13 = 17; $S14 = 22;
$S21 = 5; $S22 = 9; $S23 = 14; $S24 = 20;
$S31 = 4; $S32 = 11; $S33 = 16; $S34 = 23;
$S41 = 6; $S42 = 10; $S43 = 15; $S44 = 21;

$x = ConvertToWordArray($sMessage);
$a = 0x67452301; $b = 0xEFCDAB89; $c = 0x98BADCFE; $d = 0x10325476;

for ($k = 0; $k $AA = $a; $BB = $b; $CC = $c; $DD = $d;
// 执行MD5算法的各个步骤
md5_FF($a, $b, $c, $d, $x[$k + 0], $S11, 0xD76AA478);
md5_FF($d, $a, $b, $c, $x[$k + 1], $S12, 0xE8C7B756);
// ... (其他步骤)
$a = AddUnsigned($a, $AA);
$b = AddUnsigned($b, $BB);
$c = AddUnsigned($c, $CC);
$d = AddUnsigned($d, $DD);
}
return strtolower(WordToHex($a) . WordToHex($b) . WordToHex($c) . WordToHex($d));
}

$aaa = 'abcd';
echo php_MD5($aaa) . '
' . md5($aaa);
```

### 结论

通过对代码的详细分析和调整,我们可以使PHP自定义的MD5加密函数与ASP中的实现保持一致。尽管不同编程语言在处理相同算法时可能存在细微差异,但通过适当的调整,我们仍然可以实现跨平台的一致性。
推荐阅读
  • 2017-2018年度《网络编程与安全》第五次实验报告
    本报告详细记录了2017-2018学年《网络编程与安全》课程第五次实验的具体内容、实验过程、遇到的问题及解决方案。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 在给定的数组中,除了一个数字外,其他所有数字都是相同的。任务是找到这个唯一的不同数字。例如,findUniq([1, 1, 1, 2, 1, 1]) 返回 2,findUniq([0, 0, 0.55, 0, 0]) 返回 0.55。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • libsodium 1.0.15 发布:引入重大不兼容更新
    最新发布的 libsodium 1.0.15 版本带来了若干不兼容的变更,其中包括默认密码散列算法的更改和其他重要调整。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 网易严选Java开发面试:MySQL索引深度解析
    本文详细记录了网易严选Java开发岗位的面试经验,特别针对MySQL索引相关的技术问题进行了深入探讨。通过本文,读者可以了解面试官常问的索引问题及其背后的原理。 ... [详细]
  • 深入剖析 DEX 赛道:从 60 大头部项目看五大趋势
    本文通过分析 60 大头部去中心化交易平台(DEX),揭示了当前 DEX 赛道的五大发展趋势,包括市场集中度、跨链协议、AMM+NFT 结合、新公链崛起以及稳定币和衍生品交易的增长潜力。 ... [详细]
  • 如何使用MD5进行文件验证
    本文详细介绍MD5(Message-Digest Algorithm 5)的用途及如何通过MD5码来验证文件的完整性。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文详细介绍了Java中的输入输出(IO)流,包括其基本概念、分类及应用。IO流是用于在程序和外部资源之间传输数据的一套API。根据数据流动的方向,可以分为输入流(从外部流向程序)和输出流(从程序流向外部)。此外,还涵盖了字节流和字符流的区别及其具体实现。 ... [详细]
  • Hybrid 应用的后台接口与管理界面优化
    本文探讨了如何通过优化 Hybrid 应用的后台接口和管理界面,提升用户体验。特别是在首次加载 H5 页面时,为了减少用户等待时间和流量消耗,介绍了离线资源包的管理和分发机制。 ... [详细]
  • DCG 创始人兼首席执行官 Barry Silbert 发布致股东信,详细解答了 19 个核心问题,并分享了公司未来的发展方向。 ... [详细]
author-avatar
手机用户2502887185
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有