热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Apache源码阅读笔记一:Content-MD5字段

通常在提供下载服务时,服务器都会预先提供一个MD5校验和,用户下载完文件以后,用MD5算法计算下载文件的MD5校验和,然后通过检查这两个校验和是否一致,就能判断下载的文件是否出错。而Content-MD5是HTTP协议中一个有类似功能的字段

通常在提供下载服务时,服务器都会预先提供一个MD5校验和,用户下载完文件以后,用MD5算法计算下载文件的MD5校验和,然后通过检查这两个校验和是否一致,就能判断下载的文件是否出错。而Content-MD5是HTTP协议中一个有类似功能的字段。

Content-MD5在RFC2616中的说明是用来提供实体主体(entity-body)的 MD5 摘要(digest),为的是提供 end-to-end 消息完整性检测(MIC,可以用来检测实体主体传输过程中的偶然性变动,但不一定能防范恶意攻击)。只有源服务器或客户端可生成 Content-MD5 头域;不得由代理和网关生成,否则会有悖于其作为端到端完整性检验的价值。

任何实体主体的接收者,包括代理和网关,都可以检查此头域里的摘要值与接收到的实体主体的摘要值是否相符。但是这个字段不能保证消息没有被篡改,所以不要将它作为一种安全手段,修改正文的人同样可以修改字段的内容。

在 Apache 中我们可以通过设置 ContentDigest On 打开 Content-MD5 的输出,详细说明猛击这里

那么,在 Apache 中是如何通过设置 ContentDigest 来开启 Content-MD5 字段的输出,此字段生成的算法是怎样的?


控制 Content-MD5 字段

前面我们有说过在配置文件中增加 ContentDigest On 可以打开 Apache 的 Content-MD5 的输出,在 Apache 内核中这个配置项是如何加载的?在生成内容时是根据哪些变量控制 Content-MD5 的输出?

我们知道 Apache 的模块中有一种叫预加载模块。这些模块是 Apache 运行非常重要的模块,我们今天所说的 Content-MD5 字段就包含这些预加载模块中的一个模块 core_module 中。虽然 Apache 针对不同的操作系统有不同的预加载模块列表,但是 core_module 都会作为第一个加载的模块放在列表的最前面。

Apache 在通过 ap_setup_prelinked_modules 加载完这些预加载的模块后,其运行的基本条件已经具备。在各种池初始化后, Apache 会进行配置文件解析,并针对配置文件中每一个有效项进行循环遍历,判断这些配置项与现有模块的指令(directive)是否匹配,如果匹配并且其参数设置为在读取配置时执行(EXEC_ON_READ,Content-MD5的此参数设置为OR_OPTIONS),则执行此字段的执行函数并将此项添加到配置项的指令集中。如果没有匹配,则直接将此节点添加到指令集中。

待所有的参数加载完后,Apache 内核会执行配置树(ap_process_config_tree)的所有执行函数。根据不同的指令参数,Apache 会调用每个指令的func(不同的参数使用不同的宏,虽然现在最终都是调用 func)。回到我们关注的内容,Content-MD5字段对应的是 set_content_md5 。此函数去掉验证输入,错误处理,就剩下一句:

 
 d->content_md5 = arg != 0;

这里的arg就是我们在配置文件中的 Off 和 On,Off的值为0, On的值为1。即当 ContentDigest On 时,d->content_md5的值为1。


生成Content-MD5字段的内容

前面有说提到 Content-MD5 字段最终是由 d->content_md5 控制。除此之外,此参数的输出还与输出过滤器相关,如果输出的过滤类型不是 AP_FTYPE_RESOURCE,则不会输出 Content-MD5 字段。

如果真输出 Content-MD5 字段,则 Apache 内核会调用 ap_md5digest(/server/util_md5.c文件) 函数。 Apache 实现的 MD5 算法与标准的算法步骤有一些出入。标准算法是按照如下5个步骤进行:

  1. Append Padding Bits: 信息计算前先要进行位补位
  2. Append Length
  3. Initialize MD Buffer: 用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初始化使用的是十六进制表示的数字。
  4. Process Message in 16-Word Blocks
  5. Output: 报文摘要的产生后的形式为:A,B,C,D。也就是低位字节A开始,高位字节D结束。

因为在大多数情况下我们都无法或很难提前计算出输入信息的长度。因此在具体实现时Append Padding Bits和Append Length这两步会放在后面,如下代码:

 
    AP_DECLARE(char *) ap_md5digest(apr_pool_t *p, apr_file_t *infile) { apr_md5_ctx_t context; unsigned char buf[4096]; /* keep this a multiple of 64 */ apr_size_t nbytes; apr_off_t offset = 0L;  
        apr_md5_init(&context); nbytes = sizeof(buf); while (apr_file_read(infile, buf, &nbytes) == APR_SUCCESS) { apr_md5_update(&context, buf, nbytes); nbytes = sizeof(buf); } apr_file_seek(infile, APR_SET, &offset); return ap_md5contextTo64(p, &context); }

apr_md5_init函数执行标准算法的第三步,初始化MD缓存,而标准算法的第一步、第二步和第四步都在 apr_md5_update 中体现。最后一步输出对应 ap_md5contextTo64 。

关于MD5算法的详细算法在后续的文章中介绍。


推荐阅读
  • 深入解析Wget CVE-2016-4971漏洞的利用方法与安全防范措施
    ### 摘要Wget 是一个广泛使用的命令行工具,用于从 Web 服务器下载文件。CVE-2016-4971 漏洞涉及 Wget 在处理特定 HTTP 响应头时的缺陷,可能导致远程代码执行。本文详细分析了该漏洞的成因、利用方法以及相应的安全防范措施,包括更新 Wget 版本、配置防火墙规则和使用安全的 HTTP 头。通过这些措施,可以有效防止潜在的安全威胁。 ... [详细]
  • 负载均衡基础概念与技术解析
    随着互联网应用的不断扩展,用户流量激增,业务复杂度显著提升,单一服务器已难以应对日益增长的负载需求。负载均衡技术应运而生,通过将请求合理分配到多个服务器,有效提高系统的可用性和响应速度。本文将深入探讨负载均衡的基本概念和技术原理,分析其在现代互联网架构中的重要性及应用场景。 ... [详细]
  • 本文首先对信息漏洞的基础知识进行了概述,重点介绍了几种常见的信息泄露途径。具体包括目录遍历、PHPINFO信息泄露以及备份文件的不当下载。其中,备份文件下载涉及网站源代码、`.bak`文件、Vim缓存文件和`DS_Store`文件等。目录遍历漏洞的详细分析为后续深入研究奠定了基础。 ... [详细]
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • 如何将PHP文件上传至服务器及正确配置服务器地址 ... [详细]
  • HBase在金融大数据迁移中的应用与挑战
    随着最后一台设备的下线,标志着超过10PB的HBase数据迁移项目顺利完成。目前,新的集群已在新机房稳定运行超过两个月,监控数据显示,新集群的查询响应时间显著降低,系统稳定性大幅提升。此外,数据消费的波动也变得更加平滑,整体性能得到了显著优化。 ... [详细]
  • 进程(Process)是指计算机中程序对特定数据集的一次运行活动,是系统资源分配与调度的核心单元,构成了操作系统架构的基础。在早期以进程为中心的计算机体系结构中,进程被视为程序的执行实例,其状态和控制信息通过任务描述符(task_struct)进行管理和维护。本文将深入探讨进程的概念及其关键数据结构task_struct,解析其在操作系统中的作用和实现机制。 ... [详细]
  • Java中高级工程师面试必备:JVM核心知识点全面解析
    对于软件开发人员而言,随着技术框架的不断演进和成熟,许多高级功能已经被高度封装,使得初级开发者只需掌握基本用法即可迅速完成项目。然而,对于中高级工程师而言,深入了解Java虚拟机(JVM)的核心知识点是必不可少的。这不仅有助于优化性能和解决复杂问题,还能在面试中脱颖而出。本文将全面解析JVM的关键概念和技术细节,帮助读者全面提升技术水平。 ... [详细]
  • 深入解析Tomcat:开发者的实用指南
    深入解析Tomcat:开发者的实用指南 ... [详细]
  • Linux磁盘管理入门指南:MBR分区格式详解与安装步骤
    在 CentOS 7.x 环境下,本文详细介绍了 MBR 分区格式的基本概念及其安装步骤。实验中使用了 SAS 和 SATA 硬盘,其中 SAS 硬盘主要用于企业级应用和服务器,而 SATA 硬盘则广泛应用于个人计算机和低端服务器。文章通过具体操作示例,帮助读者更好地理解和掌握 Linux 磁盘管理的基本技能。 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • HTTP协议作为互联网通信的基础,其重要性不言而喻。相比JDK自带的URLConnection,HttpClient不仅提升了易用性和灵活性,还在性能、稳定性和安全性方面进行了显著优化。本文将深入解析HttpClient的使用方法与技巧,帮助开发者更好地掌握这一强大的工具。 ... [详细]
  • 本文深入探讨了IO复用技术的原理与实现,重点分析了其在解决C10K问题中的关键作用。IO复用技术允许单个进程同时管理多个IO对象,如文件、套接字和管道等,通过系统调用如`select`、`poll`和`epoll`,高效地处理大量并发连接。文章详细介绍了这些技术的工作机制,并结合实际案例,展示了它们在高并发场景下的应用效果。 ... [详细]
  • 如何正确配置与使用日志组件:Log4j、SLF4J及Logback的连接与整合方法
    在当前的软件开发实践中,无论是开源项目还是日常工作中,日志框架都是不可或缺的工具之一。本文详细探讨了如何正确配置与使用Log4j、SLF4J及Logback这三个流行的日志组件,并深入解析了它们之间的连接与整合方法,旨在帮助开发者高效地管理和优化日志记录流程。 ... [详细]
author-avatar
qiao203
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有