본문 바로가기
C++ 200제/코딩 IT 정보

Crypto 암호화 알고리즘 로그인 폼, WinCE MFC 다이얼로그

by vicddory 2017. 2. 20.

[MFC 다이얼로그] 암호화 로그인 폼 (WinCE Crypto 화면 예제)


[MFC 다이얼로그 예제] 테스트 장비


컴파일 테크놀로지 - CWV-070BR WinCE 터치패널PC [클릭]



MFC 다이얼로그 로그인 화면[MFC 다이얼로그 예제] 암호화 로그인폼, WinCE Crypto


■ 로그인 폼, 스크린 샷

레지스트에 User1, User2의 암호화 알고리즘인 적용된 비밀번호가 저장됩니다.


아래처럼 평문이 아닌 특수문자가 보입니다. (실제로 ㅁㅁㅁㅁㅁ로 Crypto 암호화된 건 아님)



MFC 암호화 윈도우 ce 화면 예제[MFC 다이얼로그 예제] 암호화 로그인폼, WinCE Crypto

암호화 알고리즘 적용한 비밀번호를 프로그램이 이용합니다.


프로그램은 WinCE MFC 다이얼로그 기반입니다.



wince mfc 다이얼로그 암호화[MFC 다이얼로그 예제] 암호화 로그인폼, WinCE Crypto




암호화 로그인 폼 주요 소스 확인 / 다운로드


WinCE 기반 암호화 프로젝트 Login(Crypt).zip


레지스트와 암호화 알고리즘 구현을 위해선 아래 두 개의 헤더 파일을 인클루드합니다.



1
2
#include <wincrypt.h>
#include <atlbase.h>
cs



프로그램이 시작되면 제일 먼저 레지스터 객체와 Crypto 객체를 초기화합니다.



1
2
3
4
5
6
7
8
9
10
// 공용 레지스터로 접근
RegKey.Create(HKEY_LOCAL_MACHINE, L"\\SOFTWARE\\Test");
RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"\\SOFTWARE\\Test"0, KEY_ALL_ACCESS, hKey);
 
// Crypto 객체 설정
keyBlob.header.bType = PLAINTEXTKEYBLOB;
keyBlob.header.bVersion = CUR_BLOB_VERSION;
keyBlob.header.reserved = 0;
keyBlob.header.aiKeyAlg = CALG_AES_128; // 암호 길이는 최대 15
keyBlob.cbKeySize = 16;                 // 128 바이트 사용하기에 키 사이즈는 16
cs



만약, 최초 실행이라 레지스터가 존재하지 않는다면 아래처럼 생성합니다.



암호화 로그인 폼 mfc 다이얼로그



암호화할 평문의 초기 값은 1234567890입니다. 로그인 폼 통해서 입력 받습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
char text[16];
strcpy(text, "1234567890");
 
DWORD len = (DWORD)strlen(text);
DWORD size = sizeof(text);
 
if(!CryptEncrypt(hPubKey, 0, TRUE, 0, (LPBYTE)text, &len, size))
{
    printf("Error in CryptEncrypt()\r\n");
}
else
{
    printf("encrypted looks like: %s\r\n", szClearText);
    RegKey.DeleteValue(_T("USER1"));
    RegKey.DeleteValue(_T("USER2"));
    RegKey.SetStringValue(_T("USER1"), (LPCTSTR)text);
    RegKey.SetStringValue(_T("USER2"), (LPCTSTR)text);
}
cs



ID 확인은 단순히 레지스터 데이터가 존재하는 것만 확인하면 됩니다.


중요한 건 MFC 다이얼로그에서 비밀번호를 확인하는 과정인데, 입력된 ID에 맞는 암호화 알고리즘으로 변형 된 비밀번호를 먼저 복호화합니다. 이후에 입력된 비밀번호와 일치하는지 확인하여 로그인 폼에 보여줍니다.


그 과정이 아래의 Crypto 암호화 알고리즘 소스에 해당합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
DWORD dwType;
DWORD dwSize = 16;
RegQueryValueEx(reghKey, m_strID, NULL&dwType, (LPBYTE)szDecryptText, &dwSize);
 
dwBufferSize = sizeof(szDecryptText);
 
// 레지스트에 기록된 암호화된 문자를 먼저 복호화
if(!CryptDecrypt(hPubKey, 0, TRUE, 0, (LPBYTE)szDecryptText, &dwBufferSize))
{
    printf("Error in CryptDecrypt()\r\n");
    return false;
}
else
{
    printf("decrypted looks like: %s\r\n", szDecryptText);
 
    wchar_t* pStr;
    pStr = new WCHAR[dwBufferSize];
    MultiByteToWideChar(CP_ACP, 0,szDecryptText, strlen(szDecryptText)+1, pStr, dwBufferSize);
 
    CString strTmp;
    GetDlgItem(IDC_LOG_PASSWORD)->GetWindowText(strTmp);
 
   // 복호화된 길이만큼 입력된 비밀번호와 비교
    if(wcsncmp(strTmp, pStr, dwBufferSize) == 0 && strTmp.GetLength() == dwBufferSize)
    {
        TRACE(_T("Find\r\n"));
    }
    else
    {
        printf("Please check the ID & Password\r\n");
        return false;
    }
}
cs



만약, 암호화 알고리즘 적용된 비밀번호를 교체할 경우엔 아래처럼 레지스트 데이터를 지운 후 다시 생성합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
RegKey.DeleteValue(m_strID);
RegKey.SetStringValue(m_strID, (LPCTSTR)szClearText3);
 
DWORD dwType;
DWORD dwSize = 16;
 
RegQueryValueEx(reghKey, m_strID, NULL&dwType, (LPBYTE)szClearText3, &dwDataLen);
 
dwBufferSize = sizeof(szClearText3);
 
if(!CryptDecrypt(hPubKey, 0, TRUE, 0, (LPBYTE)szClearText3, &dwBufferSize))
{
    printf("Error in CryptDecrypt()\r\n");
}
else
{
    printf("decrypted looks like: %s\r\n", szClearText3);
}
cs



mfc 폼 다이얼로그 예제 암호[Crypto 암호화 알고리즘 로그인 폼, WinCE MFC 다이얼로그]



ps. 컴파일 테크놀로지에선 더는 기술 지원을 기대하기 힘드네요.



참조 사이트

  1. Using Win32 CryptDecrypt to Decrypt [클릭]
  2. Using Win32 Crypto API to decrypt NET app RijndaelManaged [클릭]


[MFC 다이얼로그] 암호화 로그인 폼 (WinCE Crypto 화면 예제)

댓글