[原创]使用微软加密函数计算MD5哈系值 By 旖旎(于2009-2-5发表)

点此立刻下载源代码

注意本代码在编写过程中发现目前网上的在线MD5计算似乎对处理中文都有错误,得到的是错误的值,本工具得到的中文MD5和狂编兄的算法得到的一致,和ASP代码计算得到的不同。应该是ASP在处理中文有错误吧


;--------------------------------------------------------------------------------
;程序设计:中国·旖旎
;版权所有:旖旎软件 2003-2009
;禁止任何修改与盗版
;请访问64位汇编语言官方站 Http://Www.X64Asm.Com
;电子邮件 Admin@X64Asm.Com Tel:139******** 138******** QQ:6405035
;--------------------------------------------------------------------------------
;程序环境设置
.386
.model flat,stdcall
option casemap:none
;--------------------------------------------------------------------------------
;包含文件
include CryptoMd5Hash.Inc
;代码段
.code
;--------------------------------------------------------------------------------
DialogProc proc @hWin:DWORD,@uMsg:DWORD,@wParam:DWORD,@lParam:DWORD
    LOCAL    @hIcon:DWORD
    LOCAL    @hCryptProv:DWORD
    LOCAL    @hHash:DWORD
    LOCAL    @hEdit:DWORD
    LOCAL    @lpMem:DWORD
    LOCAL    @dwcbMem:DWORD
    LOCAL    @dwcbStr:DWORD
    LOCAL    @bHash[MAX_PATH]:BYTE
    LOCAL    @szHashBuff[MAX_PATH]:BYTE
    LOCAL    @dwHashLen:DWORD
    mov        eax,@uMsg
    .if eax==WM_INITDIALOG
        ;设置标题栏图标
        invoke LoadIcon,hInstance,ICON_LOGO
        mov  @hIcon,eax
        invoke SendMessage,@hWin,WM_SETICON,ICON_SMALL,@hIcon
        invoke DeleteObject,@hIcon
    .elseif eax==WM_COMMAND
        mov    edx,@wParam
        movzx    eax,dx
        shr    edx,16
        .if edx==BN_CLICKED
            .if eax==IDC_CREATE
                ;请求上下文
                invoke    CryptAcquireContext,addr @hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT or CRYPT_MACHINE_KEYSET
                .if    eax
                    ;创建哈希句柄
                    invoke    CryptCreateHash,@hCryptProv,CALG_MD5,0,0,addr @hHash
                    .if    eax
                        ;取编辑框句柄
                        invoke    GetDlgItem,@hWin,IDC_EDT
                        mov    @hEdit,eax
                        ;取编辑框输入长度
                        invoke    GetWindowTextLength,@hEdit
                        mov    @dwcbMem,eax
                        ;注意获得的长度不包括最后的零,因此必须递增
                        inc    @dwcbMem
                        ;分配内存            
                        invoke  GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,@dwcbMem
                        .if     eax
                            mov @lpMem,eax
                            ;获取输入字符串
                            invoke    GetWindowText,@hEdit,@lpMem,@dwcbMem
                            ;注意最后结尾的0不参加哈希运算,因此必须递减
                            dec    @dwcbMem
                            ;进行哈希运算
                            invoke    CryptHashData,@hHash,@lpMem,@dwcbMem,0
                            .if    eax
                                ;MD5哈希值长度为16,因此...
                                mov    @dwHashLen,16
                                ;获得哈希值(二进制)
                                invoke    CryptGetHashParam,@hHash,HP_HASHVAL,addr @bHash,addr @dwHashLen,0
                                .if    eax
                                    ;清零
                                    invoke    RtlZeroMemory,addr @szHashBuff,sizeof @szHashBuff
                                    ;二进制转化为字符串
                                    push    esi
                                    xor    esi,esi
                                    .Repeat
                                        invoke    wsprintf,addr @szHashBuff,addr szHashBuffmt,addr @szHashBuff,@bHash[esi]
                                        inc    esi
                                    .Until    esi == 16
                                    pop    esi
                                    ;输出
                                    invoke    SetDlgItemText,@hWin,IDC_EDTOUT,addr @szHashBuff
                                .endif
                            .endif
                            ;释放内存
                            invoke    GlobalFree,@lpMem
                        .endif
                        ;释放哈希句柄
                            invoke    CryptDestroyHash,@hHash
                    .endif
                    ;释放上下文
                    invoke    CryptReleaseContext,@hCryptProv,0
                .endif
            .endif    
        .endif
        
        
    .elseif eax==WM_CLOSE
        
        invoke EndDialog,@hWin,NULL
    .else
        mov        eax,FALSE
        ret
    .endif
    mov        eax,TRUE
    ret

DialogProc endp
;--------------------------------------------------------------------------------
start:
    invoke    GetModuleHandle,NULL
    mov    hInstance,eax
    invoke InitCommonControls
    invoke    DialogBoxParam,hInstance,IDD_DIALOG,NULL,addr DialogProc,NULL
    invoke    ExitProcess,NULL

;指定程序入口点
end start

并不是所有的贴子都是原创,此时作者均指发表的人而不是文章的作者,作者会说明是否是转贴