CreateProcess函数详细使用说明

作者:小菜 更新时间:2025-03-16 点击数:
简介:PTSTRpszCommandLine,PSECURITY_ATTRIBUTESpsaProcess,PSECURITY_ATTRIBUTESpsaThread

【菜科解读】

PTSTRpszCommandLine,PSECURITY_ATTRIBUTESpsaProcess,PSECURITY_ATTRIBUTESpsaThread,BOOLbInheritHandles,DWORDfdwCreate,PVOIDpvEnvironment,PCTSTRpszCurDir,PSTARTUPINFOpsiStartInfo,PPROCESS_INFORMATIONppiProcInfo);

线程调用CreateProcess时,系统会创建一个进程内核对象,将其引用计数初始化为1(进程内核对象并不是进程本身,它只是操作系统用来管理进程的数据结构,其中包含了进程的一些统计信息)。

然后系统为新进程开辟虚拟地址空间,并将可执行文件的代码和数据以及所需的DLL装载到该地址空间中。

接着系统为进程主线程创建线程内核对象,并将其引用计数初始为1(同进程一样,线程内核对象也不是线程本身,而且操作系统用来管理线程的数据结构)。

主线程将链接器设置的入口点函数作为C/C++运行时启动函数调用,这些启动函数最终又调用代码中的入口点函数如WinMain、wWinMain、main和 wmain。

当操作系统成功创建了新的进程和主线程后,CreateProcess返回TRUE。

以上是CreateProcess的简要介绍,下面我们来详细讨论它的参数。

pszApplicationName和pszCommandLine pszApplicationName和pszCommandLine分别表示进程使用的可执行文件名和向其传递的命令行字符串,我们先来看看 pszCommandLine参数。

注意pszCommandLine是PTSTR,这意味着你必须为其传递指向非常量字符串的地址。

CreateProcess内部会更改向其传递的命令行字符串,但在CreateProcess返回之前,它会将该字符串恢复原样。

这一点是非常重要的,因为如果你向CreateProcess传递的命令行字符串位于进程的只读存储区,就会发生Access Violation错误。

比如,下面的代码执行时会触发Access Violation,因为微软的C/C++编译器会把常量字符串放入只读存储区(注意早期的微软C/C++编译器会将常量字符串放在可读写存储区,因此下面的代码在旧的编译环境下不会出错):STARTUPINFOsi={sizeof(si)};PROCESS_INFORMATIONpi;CreateProcess(NULL,TEXT("NOTEPAD"),NULL,NULL,FALSE,0,NULL,NULL,&si,

解决这个问题的方法很简单,将命令行字符串复制到临时缓冲区既可,如下所示:

STARTUPINFOsi={sizeof(si)};PROCESS_INFORMATIONpi;TCHARszCommandLine[]=TEXT("NOTEPAD");CreateProcess(NULL,szCommandLine,NULL,NULL,FALSE,0,NULL,NULL,&si,

微软在其C++编译器选项中提供了/GF开关,/GF打开时,程序中所有用到的常量字符串将只维护单一副本,且位于只读存储部分。

在调用 CreateProcess时,开发人员应该打开/GF开关并使用缓冲区。

我们希望微软在未来版本的Windows中会改进CreateProcess,使其接受常量字符串作为命令行参数,并在其内部分配/释放临时缓冲区而不是让API调用者来做。

另外,假如你使用常量ANSI字符串作为 CreateProcess参数,并不会发生Access Violation错误,我们在前面的章节已经提到过,许多WinAPI函数的ANSI版本会将ANSI参数转换为UNIDOE编码后调用其 Unicode版本,CreateProcess会把ANSI字符串转换为Unicode编码后放在临时缓冲区,并调用Unicode版的 CreateProcess,因此不会触发Access Violation。

pszCommandLine参数指定了 CreateProcess创建新进程所需的完整命令行。

当CreateProcess解析该参数时,它会检查命令行参数中的第一个标记,并将其作为进程要执行的可执行文件名,如果该文件名没有指定后缀,函数将把它当作exe文件。

CreateProcess会按下面的顺序查找该文件:1. 包含当前进程可执行文件的目录2. 当前进程的当前目录3. Windows系统目录,既GetSystemDirectory返回的目录4. Windows目录5. PATH环境变量列出的目录当然,如果文件名包含了完整路径,系统将会在该路径中查找文件而不会再做上面的搜索。

如果系统找到了可执行文件,它会创建一个新的进程并把可执行文件的代码和数据映射到进程的地址空间,然后调用CRT启动函数(linker选项卡中的入口点函数),接着CRT启动函数检查命令行参数,过滤掉其中的可执行文件部分,并把剩下字符串的地址作为pszCmdLine传给wWinMain/WinMain。

以上情形都是在pszApplicationName为NULL时发生的。

pszApplicationName指定了进程要执行的可执行文件的名称,假如没有指定文件后缀,系统并不会做任何处理。

pszApplicationName不包含完整路径时,CreateProcess只从当前目录中查找可执行文件,查找失败时函数失败并返回 FALSE。

即使指定了pszApplicationName,CreateProcess仍然会将pszCommandLine参数作为新进程的命令行。

比如下面的代码://Makesurethatthepathisinaread/writesectionofmemory.TCHARszPath[]=TEXT("WORDPADREADME.TXT");//Spawnthenewprocess.CreateProcess(TEXT("C:\\WINDOWS\\SYSTEM32\\NOTEPAD.EXE"),szPath,...);

执行上面代码时,系统会打开notepad.exe(记事本),但它的命令行却是WORDPAD README.TXT(WORDPAD是写字板),这看上去非常奇怪,但CreateProcess就是这样工作的。

这种 pszApplicationName提供的特性被用来支持Windows的POSIX子系统。

psaProcess, psaThread和bInheritHandles 创建新进程时,系统会创建一个进程内核对象和一个线程内核对象(用于进程的主线程),和其它内核对象一样,创建者(在这儿是父进程)必须指定其安全属性。

psaProcess和psaThread分别指定了新进程的进程内核对象和线程内核对象的安全属性。

将其设为NULL时,系统为对应的内核对象指定默认的安全属性。

你可以创建SECURITY_ATTRIBUTES类型的变量,设置其中各个域的值然后将变量地址传递给psaProcess或 psaThread,以应用指定的安全属性。

正如在第3章讨论内核对象时谈到的,当你想要控制新的进内核对象的句柄能否被父进程以后创建的子进程继承时,你应该设置SECURITY_ATTRIBUTES变量的bInheritHandle域的值。

下面的Inherit.cpp展示了内核对象句柄继承。

假设执行该代码的进程为A,它调用CreateProcess创建了进程B,接着又创建了子进程C。

注意调用CreateProcess时A使用的psaProcess、psaThread和bInheritHandles参数,代码注释很详细的描述了这些参数的作用:/************************************************************Modulename:Inherit.cppNotices:Copyright(c)2008JeffreyRichter&ChristopheNasarre************************************************************/#includeintWINAPI_tWinMain(HINSTANCEhInstanceExe,HINSTANCE,PTSTRpszCmdLine,intnCmdShow){//PrepareaSTARTUPINFOstructureforspawningprocesses.STARTUPINFOsi={sizeof(si)};SECURITY_ATTRIBUTESsaProcess,saThread;PROCESS_INFORMATIONpiProcessB,piProcessC;TCHARszPath[MAX_PATH];//PreparetospawnProcessBfromProcessA.//Thehandleidentifyingthenewprocess//objectshouldbeinheritable.saProcess.nLength=sizeof(saProcess);saProcess.lpSecurityDescriptor=NULL;saProcess.bInheritHandle=TRUE;//Thehandleidentifyingthenewthread//objectshouldNOTbeinheritable.saThread.nLength=sizeof(saThread);saThread.lpSecurityDescriptor=NULL;saThread.bInheritHandle=FALSE;//SpawnProcessB._tcscpy_s(szPath,_countof(szPath),TEXT("ProcessB"));CreateProcess(NULL,szPath,&saProcess,&saThread,FALSE,0,NULL,NULL,&si,&piProcessB);//Thepistructurecontainstwohandles//relativetoProcessA://hProcess,whichidentifiesProcessB'sprocess//objectandisinheritable;andhThread,whichidentifies//ProcessB'sprimarythreadobjectandisNOTinheritable.//PreparetospawnProcessCfromProcessA.//SinceNULLispassedforthepsaProcessandpsaThread//parameters,thehandlestoProcessC'sprocessand//primarythreadobjectsdefaultto"noninheritable."//IfProcessAweretospawnanotherprocess,thisnew//processwouldNOTinherithandlestoProcessC'sprocess//andthreadobjects.//BecauseTRUEispassedforthebInheritHandlesparameter,//ProcessCwillinheritthehandlethatidentifiesProcess//B'sprocessobjectbutwillnotinheritahandleto//ProcessB'sprimarythreadobject._tcscpy_s(szPath,_countof(szPath),TEXT("ProcessC"));CreateProcess(NULL,szPath,NULL,NULL,TRUE,0,NULL,NULL,&si,&piProcessC);return(0);}

fdwCreate fdwCreate参数用来控制进程被创建时的行为,下面列出了它可能的取值:·DEBUG_PROCESS:父进程将调试子进程及子进程创建的所有进程,指定该参数后,在子进程或子进程创建的任意进程中发生特定事件时系统将通知父进程·DEBUG_ONLY_THIS_PROCESS:父进程将调试子进程,指定该参数后,在子进程中发生特定事件时系统将通知父进程·CREATE_SUSPENDED:进程创建后其主线程暂不执行。

此时父进程可以在子进程运行之前更改子进程地址空间中的数据、更改子进程主线程优先级、将子进程添加到作业中等。

父进程完成其更改后,可以调用ResumeThread函数恢复子进程主线程运行·DETACHED_PROCESS:系统将阻止CUI程序向其父进程的CUI窗口写入其输出。

当父进程为CUI进程时,创建的CUI子进程默认使用父进程的CUI窗口(如cmd.exe程序)。

指定该参数后,新进程在需要输出到窗口时必须调用AllocConsole创建CUI窗口·CREATE_NEW_CONSOLE:系统自动为新进程创建一个CUI窗口,该标志不能与DETACHED_PROCESS同时使用·CREATE_NO_WINDOW:系统不为新进程创建CUI窗口,使用该标志可以创建不含窗口的CUI程序·CREATE_NEW_PROCESS_GROUP:新进程将作为一个新的进程组的根进程,新的进程组将包含以根进程为祖先的所有进程。

用户在进程组中的某个进程CUI窗口中按下Ctrl+C或Ctrl+B时,系统将通知进程组中的所有进程这一事件·CREATE_DEFAULT_ERROR_MODE:子进程不继承父进程的任何错误标志·CREATE_SEPARATE_WOW_VDM:仅用于16位Windows程序,不译·CREATE_SHARED_WOW_VDM:仅用于16位Windows程序,不译·CREATE_UNICODE_ENVIRONMENT:子进程的环境块为Unicode字符串。

进程的环境块默认只包含ANSI字符串·CREATE_FORCEDOS:强制系统运行内嵌在16位OS/2系统中的MS-DOS程序·CREATE_BREAKAWAY_FROM_JOB:当父进程属于某个作业时,新建的子进程将不再与该作业关联·EXTENDED_STARTUPINFO_PRESENT:传递给CreateProcess函数的psiStartInfo参数是STARTUPINFOEX类型的变量 fdwCreate参数也可以用于设置新进程的优先级。

但你不必这样做,对大多数应用你也不应该这样做——系统会为新进程分配默认优先级。

表4-5列出了可能的优先级常量:这些常量决定了进程中的线程在CPU中调度的优先级,我们在188页的“优先级概述”中会讨论该问题。

pvEnvironment 参数pvEnvironment指向一块内存区域,其中包含新进程用到的环境字符串。

大多数情况下,你可以为其传递NULL,此时新进程将继承父进程的环境字符串。

pszCurDir 参数pszCurDir允许父进程设置子进程的当前驱动器和目录。

如果该参数为NULL,子进程将使用父进程的当前驱动器和目录作为其当前驱动器和目录。

如果pszCurDir非空,则其必须指向一个包含驱动器标识的以0结尾的路径字符串。

psiStartInfo psiStartInfo是指向STARTUPINFO或STARTUPINFOEX变量的提针:typedefstruct_STARTUPINFOEX{STARTUPINFOStartupInfo;struct_PROC_THREAD_ATTRIBUTE_LIST*lpAttributeList;}STARTUPINFOEX,*LPSTARTUPINFOEX;

Windows创建新进程时会使用STARTUPINFO(EX)的成员变量,大多数情况下可以使用这些变量的默认值,此时你应该该将其cb域设置为结构的大小,并将其余域清0,如下:

STARTUPINFOsi={sizeof(si)};CreateProcess(...,&si,...);

许多开发人员常常会忘记执行上述操作,如果你没有清空其内容,STARTUPINFO(EX)的内容会是调用线程堆栈上的一些数据。

将这些垃圾数据传递给CreateProcess可能导致无法预料的结果,为了让CreateProcess正常工作,你必须将STARTUPINFO(EX)中没有用到的域清0。

表4-6列出了STARTUPINFO(EX)结构的成员,注意有些成员只在GUI应用中生效,而有些则只在CUI应用中生效: 现在我们来讨论dwFlags成员。

dwFlags包含一组标志用来指示如何创建子进程,其中大多数标志只是告诉CreateProcess是否使用STARTUPINFO结构中的某个成员,表4-7列出了dwFlags的可取值: 另外两个标志 STARTF_FORCEONFEEDBACK和STARTF_FORCEOFFFEEDBACK可以控制在创建子进程时如何显示鼠标指针。

由于 Windows支持抢先式多任务调度,因此你可以在创建子程并等待子进程初始化时,执行另外的程序。

如果你指定了 STARTF_FORCEONFEEDBACK,Windows会在新进程初始化时将鼠标光标指针更改为“后台运行”,如下图: 这个标志意味着系统后台正在处理某些任务(在这里是创建并初始化子进程),但你依然可以继续使用系统。

当你指定了STARTF_FORCEOFFFEEDBACK标志时,CreateProcess不会更改鼠标指针样式。

如果指定了STARTF_FORCEONFEEDBACK,且子进程在CreateProcess调用后2秒内执行了GUI调用,CreateProcess会等待子进程显示窗口。

如果该GUI调用后5秒之内还没有窗口显示,CreateProcess会将鼠标指针恢复原状,否则继续等待5秒,如果在这5秒之内子进程调用了GetMessage函数,CreateProcess会认为子进程已经完成初始化并将鼠标指针复位。

STARTUPINFO的wShowWindow变量将传递给wWinMain/WinMain的最后一个参数nCmdShow,它的取值是 ShowWindow函数接受的参数值之一,通常被指定为SW_SHOWNORMAL、SW_SHOWMINNOACTIVE或 SW_SHOWDEFAULT。

在结束本节之前,我们来看看STARTUPINFOEX结构。

通过使用同时兼容STARTUPINFOEX和STARTUPINFO结构的参数psiStartInfo,微软在保持CreateProcess签名的同时提高了其扩展性。

下面是STARTUPINFOEX结构的定义:typedefstruct_STARTUPINFOEXA{STARTUPINFOAStartupInfo;struct_PROC_THREAD_ATTRIBUTE_LIST*lpAttributeList;}STARTUPINFOEXA,*LPSTARTUPINFOEXA;typedefstruct_STARTUPINFOEXW{STARTUPINFOWStartupInfo;struct_PROC_THREAD_ATTRIBUTE_LIST*lpAttributeList;}STARTUPINFOEXW,*LPSTARTUPINFOEXW;

lpAttributeList(属性链表)是_PROC_THREAD_ATTRIBUTE_LIST结构的链表,其中每个结构包含一个key/value对,目前,_PROC_THREAD_ATTRIBUTE_LIST中key的取值只能是下面两种:

PROC_THREAD_ATTRIBUTE_HANDLE_LIST:告诉 CreateProcess指定的句柄可被子进程继承,当然该句柄必须是可继承的(其继承标志位为1),且无需将CreateProcess的 bInheritHandles参数设置为TRUE。

使用该标志可以指定子进程继承可继承句柄的子集而不是全部。

这对于需要在不同的安全环境中创建子进程的进程而言非常重要,在这种情况下,由于安全原因,某些子进程可能不应该继承全部的可继承句柄。

PROC_THREAD_ATTRIBUTE_PARENT_PROCESS:指定一个进程句柄,指定的进程(包括其可继承句柄、亲缘性、优先级等等)会替代调用CreateProcess的当前进程,成为子进程的父进程。

如果当前进程在调用CreateProcess时指定了DEBUG_PROCESS或DEBUG_ONLY_THIS_PROCESS,重新指定父进程并不影响原父进程调试过程,在子进程中发生的特定事件仍然会报告给原父进程。

属性链表的内容是不透明的,因此我们需要一些函数来创建空的属性链表。

创建属性链表需要以下几个步骤,首先,为其分配存储空间,然后向其中添加键值对。

函数InitializeProcThreadAttributeList用来创建新的属性链表并为其分配存储空间:BOOLInitializeProcThreadAttributeList(PPROC_THREAD_ATTRIBUTE_LISTpAttributeList,DWORDdwAttributeCount,DWORDdwFlags,PSIZE_TpSize);

参数dwFlags必须指定为0,你可以先用如下方式获得属性链表所需的空间大小:

SIZE_TcbAttributeListSize=0;BOOLbReturn=InitializeProcThreadAttributeList(NULL,1,0,&cbAttributeListSize);//bReturnisFALSEbutGetLastError()returnsERROR_INSUFFICIENT_BUFFER

cbAttributeListSize 返回创建属性链表所需的内存大小,该大小与dwAttributeCount参数相关,dwAttributeCount指定了属性链表中的 key/value对的数目。

接下来你可以用cbAttributeListSize为属性链表分配空间:

pAttributeList=(PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(),0,cbAttributeListSize);

然后再次调用InitializeProcThreadAttributeList初始化属性链表的内容:

bReturn=InitializeProcThreadAttributeList(pAttributeList,1,0,&cbAttributeListSize);

当属性链表初始化完成后,就可以调用UpdateProcThreadAttribute向其添加键/值对了:

BOOLUpdateProcThreadAttribute(PPROC_THREAD_ATTRIBUTE_LISTpAttributeList,DWORDdwFlags,DWORD_PTRAttribute,PVOIDpValue,SIZE_TcbSize,PVOIDpPreviousValue,PSIZE_TpReturnSize);

pAttributeList是要添加键/值对的属性列表,Attribute可取 PROC_THREAD_ATTRIBUTE_PARENT_PROCESS或PROC_THREAD_ATTRIBUTE_HANDLE_LIST,取前者时,pValue参数应指向另外一个进程的句柄,cbSize取值应为sizeof(HANDLE),否则,pValue指向子进程要继承的所有内核对象的句柄数组,cbSize取值应是sizeof(HANDLE)乘以该数组的大小。

参数dwFlags、pPreviousValue和 pReturnSize是保留参数,应分别赋0、NULL和NULL。

注意,如果在创建子进程时为其指定新的父进程,既使用了 PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,那么在使用 PROC_THREAD_ATTRIBUTE_HANDLE_LIST时,pValue指向的句柄数组中的句柄应该是新父进程句柄表中对象的句柄,而不是调用CreateProcess的进程所有。

当你在CreateProcess的dwCreateFlags参数中指定了EXTENDED_STARTUPINFO_PRESENT时,你应该向CreateProcess的pStartupInfo参数传递一个STARTUPINFOEX结构的指针,如下面所示:STARTUPINFOEXesi={sizeof(STARTUPINFOEX)};esi.lpAttributeList=pAttributeList;bReturn=CreateProcess(...,EXTENDED_STARTUPINFO_PRESENT,...&esi.StartupInfo,...);

其中pAttributeList是按前面的方法创建的属性列表。

当你不再需要该属性列表时,应该调用下面的方法回收为其分配的内存:

VOIDDeleteProcThreadAttributeList(PPROC_THREAD_ATTRIBUTE_LISTpAttributeList);

最后,应用程序可以调用GetStartupInfo获得由其父进程在CreateProcess中指定的STARTUPINFO结构的拷贝:

注意,无论父进程在调用CreateProcess时参数pStartupInfo指向STARTUPINFO还是STARTUPINFOEX结构,GetStartupInfo总是返回STARTUPINFO结构的拷贝。

ppiProcInfo ppiProcInfo 参数是PROCESS_INFORMATION结构的指针,调用CreateProcess时该结构必须由开发人员手动分配。

CreateProcess 在返回前会填充ppiProcInfo指向的结构的内容。

PROCESS_INFORMATION定义如下:typedefstruct_PROCESS_INFORMATION{HANDLEhProcess;HANDLEhThread;DWORDdwProcessId;DWORDdwThreadId;}PROCESS_INFORMATION;

CreateProcess会创建一个进程内核对象和一个线程内核对象,创建初期,系统将其引用计数分别置为1。

CreateProcess返回之前会获得这两个对象的访问权限,这样每个对象的引用计数会分别增加1,CreateProcess返回之后,两个对象的引用计数变成2。

这意味着如果系统要释放CreateProcess进程/线程内核对象,相应的进程/线程必须终止,并且调用CreateProcess的线程必须调用 CloseHandle关闭相应的对象句柄,这样才能使得其引用计数变为0,系统方能释放。

CreateProcess,函数,详细,使用说明,函数,原型

MD5是什么?从原理到应用的详细解析

想重装系统不会怎么办?菜科网一键重装系统轻松在线帮您搞定系统重装问题。

软件支持 在线重装、U盘制作、自定义重装 等多种模式。

简介:MD5,全称为Message-Digest Algorithm 5,是一种广泛用于计算机安全领域的哈希函数。

MD5能够将任意长度的数据输入,经过复杂的运算后,生成一段长度为128位的散列值(通常以32位十六进制数表示)。

正因其出色的数据完整性与一致性验证能力,MD5被广泛应用于文件验证、数字签名等多个领域。

在本文中,我们将详细解析MD5的原理以及其具体应用。

工具原料:系统版本:Windows 11、macOS Ventura品牌型号:Dell XPS 13、Apple MacBook Air M2软件版本:OpenSSL 1.1.1、HashTab v6.0一、MD5原理解析1、MD5的工作原理可以分为四个步骤:填充过程、初始化MD缓冲区、处理分组和输出结果。

2、填充过程是将原始消息填充至其长度等于448 mod 512比特。

填充内容为一个1后跟多个0,最终消息长度比原长度少64比特。

3、初始化MD缓冲区则是开始将一个包含4个32位寄存器的缓冲区初始化为一定固定值。

4、处理分组步骤中,消息被分成多个512比特分组,每个分组需进行64次运算。

运算包括位运算、加法运算等复杂步骤,操作每个分组的数据在缓冲区中转化形成新的数据。

5、输出结果即为最后缓冲区的内容,经转换后成为MD5散列值。

二、MD5在数据验证中的应用1、文件完整性验证:MD5常用于验证文件下载过程中的完整性。

通过比对下载文件与服务器文件的MD5值检测数据传输过程是否受损。

2、版本管理工具中的应用:许多版本管理工具(如Git)使用MD5散列值作为确认标识,以确保代码库的完整性及版本一致性。

3、密码加密(不推荐): 虽然MD5曾用于存储用户密码的加密,但由于其碰撞现象(即不同输入得到相同MD5值)已经被验证,MD5已不再安全。

因此,现代系统一般不使用MD5用于保护密码,而更倾向于采用更安全的SHA-256等散列方法。

三、实例场景及工具案例1、以Windows和macOS为例,通过使用HashTab这样的软件来计算文件的MD5值,是了解文件完整性的重要步骤。

用户只需右键点击文件属性,即可查看其MD5值。

2、在使用OpenSSL时,你可以通过命令行操作生成文件的MD5值。

例如,执行“openssl md5 filename”,输出结果即为文件的MD5散列值。

3、IT专业人员和网络管理员通常批量验证服务器端文件的完整性,以防数据被篡改。

拓展知识:1、随着技术的发展,MD5的安全性逐步被削弱。

它的碰撞攻击被多次验证,因此,被认为不能提供足够的安全保障。

时至今日,MD5主要用于验证数据完整性,而非数据安全性。

2、SHA (Secure Hash Algorithm) 系列中的SHA-256或SHA-3已成为更安全的替代算法,这些方法提供了更长的散列值以及更加复杂的运算步骤。

3、数字签名流程中,虽然MD5不再被推荐使用,但其基本操作思路被继承下来,广泛应用于其他更为安全的散列函数中。

总结:MD5是一种重要的散列函数,曾因其效率和简单性成为多种操作的标配。

然而,随着网络安全威胁的增加,MD5的一些安全漏洞也逐渐被揭露。

因此,在涉及安全性要求较高的应用中,MD5逐渐被更安全的算法,比如SHA-256所取代。

不过,在文件完整性验证方面,MD5仍然扮演着不可或缺的角色。

在快速技术更新的时代里,因地制宜选择正确的散列函数是维护数据安全的关键。

标签: 注意:本站所刊载的文章均为学习交流之用,请勿用于商业用途。

对于商业使用,请联系各自版权所有者,否则法律问题自行承担。

腾达路由器地址设置指南:快速解决网络连接问题 2024年大学生笔记本电脑推荐:实用机型排行榜最新整理 MD5是什么?从原理到应用的详细解析 分类于: 回答于:2025-02-11 简介:MD5,全称为Message-Digest Algorithm 5,是一种广泛用于计算机安全领域的哈希函数。

MD5能够将任意长度的数据输入,经过复杂的运算后,生成一段长度为128位的散列值(通常以32位十六进制数表示)。

正因其出色的数据完整性与一致性验证能力,MD5被广泛应用于文件验证、数字签名等多个领域。

在本文中,我们将详细解析MD5的原理以及其具体应用。

工具原料:系统版本:Windows 11、macOS Ventura品牌型号:Dell XPS 13、Apple MacBook Air M2软件版本:OpenSSL 1.1.1、HashTab v6.0一、MD5原理解析1、MD5的工作原理可以分为四个步骤:填充过程、初始化MD缓冲区、处理分组和输出结果。

2、填充过程是将原始消息填充至其长度等于448 mod 512比特。

填充内容为一个1后跟多个0,最终消息长度比原长度少64比特。

3、初始化MD缓冲区则是开始将一个包含4个32位寄存器的缓冲区初始化为一定固定值。

4、处理分组步骤中,消息被分成多个512比特分组,每个分组需进行64次运算。

运算包括位运算、加法运算等复杂步骤,操作每个分组的数据在缓冲区中转化形成新的数据。

5、输出结果即为最后缓冲区的内容,经转换后成为MD5散列值。

二、MD5在数据验证中的应用1、文件完整性验证:MD5常用于验证文件下载过程中的完整性。

通过比对下载文件与服务器文件的MD5值检测数据传输过程是否受损。

2、版本管理工具中的应用:许多版本管理工具(如Git)使用MD5散列值作为确认标识,以确保代码库的完整性及版本一致性。

3、密码加密(不推荐): 虽然MD5曾用于存储用户密码的加密,但由于其碰撞现象(即不同输入得到相同MD5值)已经被验证,MD5已不再安全。

因此,现代系统一般不使用MD5用于保护密码,而更倾向于采用更安全的SHA-256等散列方法。

三、实例场景及工具案例1、以Windows和macOS为例,通过使用HashTab这样的软件来计算文件的MD5值,是了解文件完整性的重要步骤。

用户只需右键点击文件属性,即可查看其MD5值。

2、在使用OpenSSL时,你可以通过命令行操作生成文件的MD5值。

例如,执行“openssl md5 filename”,输出结果即为文件的MD5散列值。

3、IT专业人员和网络管理员通常批量验证服务器端文件的完整性,以防数据被篡改。

拓展知识:1、随着技术的发展,MD5的安全性逐步被削弱。

它的碰撞攻击被多次验证,因此,被认为不能提供足够的安全保障。

时至今日,MD5主要用于验证数据完整性,而非数据安全性。

2、SHA (Secure Hash Algorithm) 系列中的SHA-256或SHA-3已成为更安全的替代算法,这些方法提供了更长的散列值以及更加复杂的运算步骤。

3、数字签名流程中,虽然MD5不再被推荐使用,但其基本操作思路被继承下来,广泛应用于其他更为安全的散列函数中。

总结:MD5是一种重要的散列函数,曾因其效率和简单性成为多种操作的标配。

然而,随着网络安全威胁的增加,MD5的一些安全漏洞也逐渐被揭露。

因此,在涉及安全性要求较高的应用中,MD5逐渐被更安全的算法,比如SHA-256所取代。

不过,在文件完整性验证方面,MD5仍然扮演着不可或缺的角色。

在快速技术更新的时代里,因地制宜选择正确的散列函数是维护数据安全的关键。

菜科网系统致力于解决 Windows 系统重装解决方案,提供高效、安全、免费的系统重装服务。

详细讲解win10数字许可证激活原理

专业的在线重装系统软件 全新设计 / 全新代码编写 / 全新支持所有机型 全新支持Window 11 安装 数字权利激活英文也称之为:Digital License Activation。

它是在 Windows 10 系统中新推出的一种全新的 Windows 激活方式,通过使用该激活方式您可以不需要输入产品密钥即可完成在线激活。

什么是数字权力激活?数字权利(Digtal Entitlement, 微软官方称作数字授权):是随着 Windows 10 推出的一种激活方法,通过该方法,并不需要输入产品密钥。

在 Windows 10 Build 1511 版本后,微软更改了叫法 - 数字许可证(Digital License)。

数字许可证是与硬件直接关联,并且可以链接到微软帐户中,新购买的正版 window s电脑,登录微软账号,并联网,就完成了数字许可证的绑定。

(在系统设置- 激活页面,可以查看系统激活是否是属于数字许可证书)数字权利激活方式原理是什么?用过 Windows 7 可能都清楚,曾经有很长一段时间,可以免费升级到 Windows 10,只要 Windows 7 是激活的,那么升级到 Windows 10 就自动激活了。

Windows 7/8/8.1 升级到 Windows 10 时,简单来说,就是以下的过程:执行安装包中的 gatherosstate.exe 程序,该 exe 会生成一个包含当前硬件信息及其他信息的 xml 文件生成的 xml 文件将会被上传到微软的服务器并反馈一个 json 文件。

这个激活过程是比较费时的,并不像点击“激活”按钮那种方式那么简单。

国外一些大神发现了一种方式: 通过欺骗 gatherosstate.exe,就可以快速的生成一个有效的 xml 文件。

这个就是数字权利激活方式的简单原理。

其实目前无论是使用数字激活方式还是 KMS 激活方式都可以激活 Windows 10 系统,最主要的还是我们在使用时要考虑购买正版即可。

加入收藏
               

CreateProcess函数详细使用说明

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录