천객만래 [千客萬來] (It has an interminable succession of visitors)

MD5 암호화를 찾아보면서...

MD5 암호화 리턴값이 다른 경우가 꽤나 있다. 그래서 windows에서 제공하는 WinAPI32 를 사용하기로 했다.

WinCrypt API를 사용하기로 했다.

그리고, 값이 제대로 나오는 방법을 찾아서 구현했다.


또, 아래 사이트가 내가 구현한 것과 거의 유사하다.


아래 소스가 공유가 많이 되었으면 좋겠다. 동일한 md5 암호화 값이 나오게




[개발/Delphi] WinCrypt API32 로 문자열 MD5 암호화 하기



출처: http://www.scalabium.com/faq/dct0173.htm


function MD5(const Value: string): string;
var
  hCryptProvider: HCRYPTPROV;
  hHash: HCRYPTHASH;
  bHash: array[0..$7F] of Byte;
  dwHashLen: dWord;
  i: Integer;
begin
  dwHashLen := 16;
  if (Value = '') then
  begin
    Result := 'd41d8cd98f00b204e9800998ecf8427e';
    exit;
  end
  else
    Result := '';

  {get context for crypt default provider}
  if CryptAcquireContext(@hCryptProvider, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT or CRYPT_MACHINE_KEYSET) then
  begin
    {create hash-object MD5}
    if CryptCreateHash(hCryptProvider, CALG_MD5, 0, 0, @hHash) then
    begin
      {get hash from password}
      if CryptHashData(hHash, @Value[1], Length(Value), 0) then
      begin
        if CryptGetHashParam(hHash, HP_HASHVAL, @bHash[0], @dwHashLen, 0) then
        begin
          for i := 0 to dwHashLen-1 do
            Result := Result + IntToHex(bHash[i], 2);
        end;
      end;
      {destroy hash-object}
      CryptDestroyHash(hHash);
    end;
    {release the context for crypt default provider}
    CryptReleaseContext(hCryptProvider, 0);
  end;

  Result := AnsiLowerCase(Result);
end;

Posted by SB패밀리
[mfc] WINDOWS API를 이용한 암호화 간단 예제

#include "stdafx.h"
#include <Windows.h>
#include <WinCrypt.h>

#define    MY_PASS       "papaya"           // 패스워드
#define    KeyLen        0x0080 * 0x10000    // 128-bit

int _tmain(int argc, _TCHAR* argv[])
{

    HCRYPTPROV    hProv;
    HCRYPTHASH    hHash;
    HCRYPTKEY     hKey;

    BYTE          pbData[100] = "TEST TEST TEST REAL TEST";
    DWORD         dwDataLen = (DWORD)strlen((char*)pbData) + 1;

    // CSP(Crystographic Service Provider) 핸들 얻기

    if(!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, 
                            PROV_RSA_FULL, 0))
    {
        // 유저용 키 컨테이너 만들기
        if(!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV,
                                PROV_RSA_FULL, CRYPT_NEWKEYSET))
        {
            printf("유저용 키 켄테이너 만들기 에러\n");
            return 1;
        }
    }

    // 해쉬 만들기
    if(!CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash))
    {
        printf("해쉬 만들기 에러\n");
        return 2;
    }

    // 해쉬 값 계산
    if(!CryptHashData(hHash, (BYTE*)MY_PASS, (DWORD)strlen(MY_PASS), 0))
    {
        printf("해쉬 값 계산 에러\n");
        return 3;
    }

    // 키 만들기
    if(!CryptDeriveKey(hProv, CALG_RC4, hHash, KeyLen, &hKey))
    {
        printf("키 만들기 에러\n");
        return 4;
    }

    // 암호화
    if(!CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 100))
    {
        printf("암호화 에러\n");
        return 5;
    }
    printf("암호건 문자 -> %s\n", pbData);

    // 복호화
    if(!CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen))
    {
        printf("복호화 에러\n");
        return 6;
    }
    printf("암호푼 문자 -> %s\n", pbData);

    // 해쉬 없애기
    CryptDestroyHash(hHash);

    // CSP 핸들 풀어주기
    CryptReleaseContext(hProv, 0);

    return 0;
}


Posted by SB패밀리