티스토리 뷰
목차
[MFC 다이얼로그] 암호화 로그인 폼 (WinCE Crypto 화면 예제)
■ 로그인 폼, 스크린 샷
레지스트에 User1, User2의 암호화 알고리즘인 적용된 비밀번호가 저장됩니다.
아래처럼 평문이 아닌 특수문자가 보입니다. (실제로 ㅁㅁㅁㅁㅁ로 Crypto 암호화된 건 아님)
[MFC 다이얼로그 예제] 암호화 로그인폼, WinCE Crypto
암호화 알고리즘 적용한 비밀번호를 프로그램이 이용합니다.
프로그램은 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 |
만약, 최초 실행이라 레지스터가 존재하지 않는다면 아래처럼 생성합니다.
암호화할 평문의 초기 값은 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 |
[Crypto 암호화 알고리즘 로그인 폼, WinCE MFC 다이얼로그]
ps. 컴파일 테크놀로지에선 더는 기술 지원을 기대하기 힘드네요.
참조 사이트
- Using Win32 CryptDecrypt to Decrypt [클릭]
- Using Win32 Crypto API to decrypt NET app RijndaelManaged [클릭]
[MFC 다이얼로그] 암호화 로그인 폼 (WinCE Crypto 화면 예제)