2015 년정보보호학과졸업작품보고서 USB 를이용한 System Lock 및 File Security Service 팀명 : Team IU ( Intelligent USB ) 지도교수 : 양정모교수님 조장 : 조상일 유승우 조한슬 2015. 6 중부대학교정보보호학과
목 차 Ⅰ. 서론 Ⅰ-1. 프로젝트소개 Ⅰ-2. 연구활동배경 Ⅰ-3. 피해사례조사 Ⅱ. 본론 Ⅱ-1. 프로그램구성 Ⅱ-2. 파일의암호화후백업및복호화후복원 Ⅱ-3. 화면잠금 Ⅱ-4. 소스코드 Ⅲ. 결론 Ⅲ-1. 기대효과 Ⅲ-2. 프로그램의향후발전, 개선방향 Ⅳ. 참고자료 Ⅳ-1. 참고알고리즘, 블로그 Ⅴ. 별첨 Ⅴ-1. 발표 PPT
Ⅰ. 서론 Ⅰ-1. 프로젝트소개 1. 프로젝트제목 USB 를이용한 System Lock 및 File Security Service 2. 프로젝트선정사유 최근경량노트북의보급이급증되었으나많은사용자들은비밀번호를이용한화면잠금등보안기능을적절히사용하지않아각종파일에기록되어있는개인정보가유출될수있는위험이항상존재하고있습니다. 이외에도누구나쉽게구할수있고대중적으로사용되는 USB의경우휴대가편리하면서대용량인경우가많아많은사람이사용하고있지만이 USB가분실될경우, 내장되어있는중요한정보의백업이나정보의유출에따른피해는누구도보상할수없는현실이기때문에이러한문제점들을해결하기위하여본프로젝트를선정하였습니다. 3. 프로젝트연구내용 Visual C 를기반으로하는 Window32 API 를사용하여화면잠금과특정파일의암호화를 구현하였고, C++ 전용 AES128 암호알고리즘을 C 에맞추어변형시켜서적용하였습니다. 4. 프로젝트요약 저희는위의두가지문제점이라는토끼를한번에잡기위하여 USB를이용하여버튼하나로실행되는강력한화면잠금기능을구현하여 PC나노트북등에저장된정보를 1차적으로보호하여미리저장해둔 Hash값이서로 Matching되는 USB를소지한사용자만이화면잠금을해제할수있도록구현함과동시에 USB에저장된중요한파일의경우는사용자의과실로인한분실에따른개인정보의유출을방지하기위하여파일의내용을암호화하여알아볼수없게하는기능과적용된암호를복호화가가능하도록구현하였습니다. - 3 -
Ⅰ-2. 연구활동배경 - 현대사회를살아감에있어서정보의의미는개인이나특정기업혹은단체와국가에 이르기까지그필요성과중요성을널리인식하고있는반면아직그정보를보호하고자하는 개개인의노력은아직도부족하고미흡한편이라고감히말할수있습니다. 이에저희 Team I.U는소형 USB 하나로 2가지의기본적인보안기능을제공하는연구를시작하였습니다. 본연구활동의결과로만들어진프로그램을적절히사용할경우개인적인정보뿐만아니라기업, 단체또는국가의정보를개인이관리함에있어서한층더강화된보안기능을제공받을수있습니다. 본연구활동의주요기능은크게화면잠금과암호화기능으로나눌수있습니다. 우선화면잠금기능을구현하기위해 Windows32 API 를사용하였는데, 이윈도 API는마이크로소프트 32비트윈도운영체제들이사용하는 API입니다. C/C++ 개발프로그램에서직접운영체제와상호작용할수있도록만들어졌으며, 이 API에소속된 DLL(Dynamic Link Library) 중 WinLockDLL 이란라이브러리를사용하여구현하였습니다. 암호화기능은현재 Open Source로공개되어있는 AES 암호를사용하였습니다. 이 AES 암호란 Advanced Encryption Standard의약자로, 존대먼, 빈센트라이먼이만든암호화알고리즘입니다. NIST가제정하였고미국정부가공식적으로채택하게된후널리사용되고있습니다. 128Bit, 192Bit, 256Bit 3가지종류를지원하는암호알고리즘이지만본연구에서는속도의최적화를위해 128Bit 방식을사용하였습니다. 특히이암호화기능의강도를유지하기위해사용하는해시함수 (Hash Function) 를사용하는데이는임의의길이데이터를일정한길이의데이터로 Mapping시키는알고리즘입니다. 해시함수는결정론적으로작동해야하며, 따라서두해시값이다르다면그해시값에대한원래데이터도달라야하며, 역은성립하지않는특징이있습니다. 해시함수중에는암호학적해시함수 (Cryptographic Hash Function) 와비-암호학적해시함수로구분되곤합니다. 저희는이 Hash 함수중 SHA-1 함수를사용하였습니다. SHA(Secure Hash Algorithm) 함수들은서로관련된암호학적해시함수들의모음입니다. 이들함수는미국국가안보국 (NSA) 이 1993년에처음으로설계했으며미국국가표준으로지정되었던함수입니다. 기존의 SHA-1 이외에도 4종류의변형 (SHA-224, SHA-256, SHA-384, SHA-512) 가발표되었으며, 이들을통칭해서 SHA-2라고하기도합니다. SHA-1 은 SHA 함수들중가장많이쓰이며, TLS, SSL, SSH, IPSec 등많은보안기능을 지원하는프로토콜과프로그램에서사용되고있습니다. 본연구에서는속도의최적화를위해 비교적간단한 SHA-1 을사용하였습니다. - 4 -
Ⅰ-3. 피해사례조사 < 그림 -1.3(1) 개인정보침해관련사건자료 > 위의통계에서확인할수있는점은사고대상의업종과는관계없이개인정보의 관리미흡으로인한유출사태가끊임없이일어나고그추세또한급격히상승하고 있다는것을확인할수있습니다. 위와같은피해사례중개인의부주의등인적과실로인한피해는작은경각심과 보안의식을갖고있다면누구나예방할수있을것이라고생각되어연구를진행하게 되었습니다. - 5 -
< 그림 -1.3(2) 고객정보유출시금융기관이입는피해 > 위의자료는고객의정보유출피해가발생했을때기업이직접적으로타격을입을수있는부분입니다. 일례로 SK communications의 NateON과 Cyworld 서비스의경우대량의개인정보유출사건당시고객들은 SK를상대로집단소송을이행한바있으며, 사용자의대규모이탈의직접적인원인이되어현재는그명맥만잇고있는현실입니다. 또다른예로는농협의대량개인정보유출사건당시많은고객들이신뢰를잃고 농협과의모든금융거래를중지하고신용정보를파기한후타사은행의고객으로 유입된바가있습니다. - 6 -
< 그림 -1.3(3) 개인정보유출사고시구제방법및한계 > 위의자료에서확인할수있듯해커의악의적인수법으로인한사용자의개인정보유출이일어났을때에는해당기업에게보상을청구할수있는법적근거가마련되어있지만, 만약직원이나내부관계자의부주의로인한사고로인한보상은어디에도나타나있지않습니다. 모든책임을특정인에게전가하기에는기업이나사고의원인이된당사자측모두부담이뒤따르기때문입니다. 저희는본연구를통해제작된프로그램으로위와같은사건, 사고를사전에미리 예방하고자하여실시하게되었습니다. - 7 -
Ⅱ. 본론 Ⅱ-1. 프로그램구성 - USB 인식후잠금해제를위한 PW 파일확인 - WinLockDLL 을이용한화면잠금 - PC( 노트북 ) USB 간의파일암호화백업, 복호화복원 < 그림 -2.1(1) 프로그램구조 > < 그림 -2.1(2) 프로그램메인화면 > - 8 -
Ⅱ-2. 파일의암호화후백업및복호화후복원 파일백업 Flow Chart < 그림 -2.2 파일백업 Flow Chart > 파일의백업기능은기존의 Copy & Paste를이용하는수동방식을개선한형태로폴더를지정한뒤클릭한번으로백업및암호화기능이실행되게구축하여인식된상태인 USB의최상위 Directory에 Backup 이라는이름의폴더를생성한후 AES-128 암호를적용하여저장하게되고, 복호화를선택할경우기존에백업을시도했던경로에동일한방식의암호를역산하는방식으로복호화한뒤저장합니다. 기능의동작순서는프로그램을실행후메인화면에서 드라이브선택 메뉴를통한백업드라이브 (USB) 를선택후 Write가가능한지여부를판단하게됩니다. 만약 Write가가능한드라이브라면백업할파일을지정한후암호화가가능한파일형식인지의여부를확인한후에백업과동시에파일암호화키를생성하게되고키를저장합니다. 복호화시에는생성되었던키값에 Hash 함수를적용한결과값이 USB 에저장된것과 PC 에 저장되어있는것이일치하는지여부를확인후일치한다면복호화가이루어지게됩니다. 모든선택문에서 False 값으로판단될경우이전단계로돌아가메뉴를재선택하게됩니다. - 9 -
Ⅱ-3. 화면잠금 화면잠금 Flow Chart < 그림 -2.3 화면잠금 Flow Chart > 본프로그램이실행된적이없는 USB를 PC나노트북에삽입하여정상적으로인식된경우프로그램을실행한후파일백업메뉴의 Step 1에서보여지는드라이브를선택하는화면에서인식된드라이브 ( 현재구동중인 PC의경우 G:\) 에 LockKey.dat 이라는파일을숨김형태로생성하여 Hash 함수인 SHA-1를적용시킨 PW파일로지정후화면잠금해제시도가있을때 (USB Output 후다시 Input 시 ) 매칭을확인하여잠금을해제할수있습니다. 기능의동작순서는메인화면에서화면잠금해제의키값을저장할 USB 드라이버를선택후우측상단 화면잠금 버튼을클릭시화면이잠금설정되게됩니다. 만약화면잠금을해제할키를 USB에저장하지않고기능을실행시잠금해제가불가능하기때문에사용중인 PC를재부팅하여야합니다. USB 삽입시저장된화면잠금해제용키값이정상적인 PW 파일로인식되면화면잠금을 해제하게됩니다. 모든선택문에서 False 값으로판단될경우이전단계로돌아가대기하게됩니다. - 10 -
Ⅱ-4. 소스코드 #define WIN32_LEAN_AND_MEAN #include "stdafx.h" #include "resource.h"--- #include "Logfile.h" #include "../../WinLockDLL/WinLockDLL/winlockdll.h" #include "Shlwapi.h" #include <dbt.h> #include <windows.h>// 파일복사 #include <shlwapi.h>//lockkey.txt 파일검사 #include <WinCrypt.h>// 파일암호화 #pragma comment(lib, "Shlwapi.lib") #define PROGRAM_MANAGER "Program Manager" // Program manager window name #define TASKBAR "Shell_TrayWnd" // Taskbar class name //#define MY_PASS "NALNARI" // 패스워드 // 파일암호화 #define KeyLen 0x0080 * 0x10000 // 128-bit // 파일암호화 HHOOK hhook; // Mouse hook HINSTANCE hinst; // Instance handle HINSTANCE g_hinstance; HWND hwnd ; // 파일생성및쓰기 static HANDLE hfile; static DWORD result; static int GStr; // 파일읽기 static HANDLE R_hFile; static HANDLE f_hfile; static DWORD RRead; static DWORD FRead; static TCHAR Rstring[21]; static TCHAR fstring[21]; static int RStr; static DWORD ppbdata;// 암호화 // 파일생성및검사 TCHAR Txtname[128]=TEXT(":\\LockKey.dat");// 파일이름 TCHAR CTxtname[128]=TEXT("D"); TCHAR Tempname[128]; TCHAR *ftxtname[128]=text("e"),text("f"),text("g"),text("h"),text("i"),text("j"); TCHAR copytxtname[128]; - 11 -
//LPCTSTR lpszclass=text("screen Lock"); // 파일내용암호화 HCRYPTPROV hprov; HCRYPTHASH hhash; HCRYPTKEY hkey; BYTE pbdata[100] = "TSTWPSELSIDWLSEP" BYTE MY_PASSKEY; BYTE MY_PASSWD[100]; DWORD dwdatalen = (DWORD)strlen((char*)pbData) + 1; // 폴더복사 TCHAR FolderCP[128]; TCHAR FolderCP2[128]; TCHAR NUL[1]; #define DESKTOPNAME "MyDesktop2" // New desktop name THREAD_DATA td; static WCHAR buf[1024]; static char cbuf[1024]; bool g_bunlock = false // 파일암호화 // wstrsrcfn : 원시파일명 // wstrdestfn : 목적파일명 // hkey : 암호화키 HRESULT FileEncryption( WCHAR *wstrsrcfn, WCHAR *wstrdestfn, HCRYPTKEY hkey ) if( wstrsrcfn == NULL wstrdestfn == NULL hkey == NULL ) return S_FALSE; HANDLE DWORD DWORD char hsrcfile, hdestfile; nnumberofbytestoread, lpnumberofbytesread; lpnumberofbyteswritten; strbuffer[1024]; // 원시파일오픈 hsrcfile = CreateFile( wstrsrcfn, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( hsrcfile == INVALID_HANDLE_VALUE ) return S_FALSE; // 목적파일오픈 hdestfile = CreateFile( wstrdestfn, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); nnumberofbytestoread = sizeof(strbuffer); - 12 -
); while(1) // 원시파일로부터일정량 (nnumberofbytestoread) 의데이터를읽는다. ReadFile( hsrcfile, strbuffer, nnumberofbytestoread, &lpnumberofbytesread, NULL // 읽어들인데이터가없을경우종료 if( lpnumberofbytesread <= 0 ) break // 암호화 CryptEncrypt( hkey, 0, TRUE, 0, (BYTE *)strbuffer, &lpnumberofbytesread, sizeof(strbuffer) ); // 암호화처리된데이터를목적파일에저장 WriteFile( hdestfile, strbuffer, lpnumberofbytesread, &lpnumberofbyteswritten, NULL ); CloseHandle( hdestfile ); // 오픈된목적파일핸들닫기 CloseHandle( hsrcfile ); // 오픈된원시파일핸들닫기 return S_OK; // 파일복호화 // wstrsrcfn : 원시파일명 // wstrdestfn : 목적파일명 // hkey : 복호화키 HRESULT FileDecryption( WCHAR *wstrsrcfn, WCHAR *wstrdestfn, HCRYPTKEY hkey ) if( wstrsrcfn == NULL wstrdestfn == NULL hkey == NULL ) return S_FALSE; HANDLE hsrcfile, hdestfile; DWORD nnumberofbytestoread, lpnumberofbytesread; DWORD lpnumberofbyteswritten; char strbuffer[1024]; // 원시파일오픈 hsrcfile = CreateFile( wstrsrcfn, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( hsrcfile == INVALID_HANDLE_VALUE ) return S_FALSE; // 목적파일오픈 hdestfile = CreateFile( wstrdestfn, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if( hdestfile == INVALID_HANDLE_VALUE ) CloseHandle( hsrcfile ); // 오픈된원시파일핸들닫기 return S_FALSE; nnumberofbytestoread = sizeof(strbuffer); - 13 -
); while(1) // 원시파일로부터일정량 (nnumberofbytestoread) 의데이터를읽는다. ReadFile( hsrcfile, strbuffer, nnumberofbytestoread, &lpnumberofbytesread, NULL // 읽어들인데이터가없을경우종료 if( lpnumberofbytesread <= 0 ) break // 복호화 CryptDecrypt( hkey, 0, TRUE, 0, (BYTE *)strbuffer, &lpnumberofbytesread ); // 암호화처리된데이터를목적파일에저장 WriteFile( hdestfile, strbuffer, lpnumberofbytesread, &lpnumberofbyteswritten, NULL ); CloseHandle( hdestfile ); // 오픈된목적파일핸들닫기 CloseHandle( hsrcfile ); // 오픈된원시파일핸들닫기 return S_OK; //LRESULT CALLBACK WndProc(HWND hwnd,uint imessage,wparam wparam,lparam lparam); INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam); INT_PTR CALLBACK UnlockEditProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam); BOOL BrowseFolder(HWND hparent, LPCTSTR sztitle, LPCTSTR StartPath, TCHAR *szfolder); char Remove(char* in_hasgenre); BOOL XCopy(LPCTSTR Src, LPCTSTR Dest); //BOOL FileEncryption(LPCTSTR Src,LPCTSTR Dest);//, LPCTSTR Dest); BOOL FileEncryption(LPCTSTR Src, LPCTSTR Dest,HWND hwnd);//, LPCTSTR Dest) // Foldercp FolderCP2가들어와야함 BOOL FileDecryption(LPCTSTR Src, LPCTSTR Dest,HWND hwnd);//, LPCTSTR Dest) // Foldercp FolderCP2가들어와야함 INT_PTR CALLBACK HelpProc(HWND hdlg, UINT Message, WPARAM wparam, LPARAM lparam); INT_PTR CALLBACK MakerProc(HWND hdlg, UINT Message, WPARAM wparam, LPARAM lparam); INT_PTR CALLBACK OkProc(HWND hdlg, UINT Message, WPARAM wparam, LPARAM lparam); //void hex2byte(const char *in, int len, byte *out);// 파일암호화 //void encryp(); DWORD WINAPI MyThread(LPVOID lpparameter) SetThreadDesktop(((THREAD_DATA *)lpparameter)->hdesk); g_bunlock = false DialogBox( g_hinstance, MAKEINTRESOURCE(IDD_LL), HWND_DESKTOP, UnlockEditProc ); while(!g_bunlock ) Sleep(10); return 0; - 14 -
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) return 0; //HWND hwnd; //MSG Message; //WNDCLASS WndClass; g_hinstance = hinstance; DialogBox( g_hinstance, MAKEINTRESOURCE(IDD_MAIN), HWND_DESKTOP, MainDlgProc ); int i=0,j=0; HWND hedit; INT_PTR CALLBACK MainDlgProc(HWND hdlg, UINT Message, WPARAM wparam, LPARAM lparam) //RECT r; TCHAR usblist[128];// 암호키생성 static TCHAR StartPath[MAX_PATH]; TCHAR Folder[MAX_PATH]; TCHAR File[MAX_PATH]=TEXT("*.");// 리스트박스 char filetest[max_path];//([--] 제거할때 ) 형변환 switch(message) case WM_CREATE: HWND hcombo; hcombo=getdlgitem(hdlg, IDOK); SetFocus(hCombo); return TRUE; //USB 선택리스트박스 case WM_INITDIALOG: DlgDirList(hDlg, File, IDC_LIST2, 0, (DDL_DRIVES)); return TRUE; //USB 인식부분 case WM_DEVICECHANGE: switch (LOWORD(wParam)) case DBT_DEVICEARRIVAL: DlgDirList(hDlg, File, IDC_LIST2, 0, (DDL_DRIVES)); break case DBT_DEVICEREMOVECOMPLETE: DlgDirList(hDlg, File, IDC_LIST2, 0, (DDL_DRIVES)); break default: break return TRUE; - 15 -
case WM_COMMAND: switch (LOWORD(wParam)) // 화면잠금버튼 case IDOK: MessageBox(hWnd, TEXT("USB를분리해주세요 "), TEXT(" 확인 "),MB_OK); strcpy(td.szdesktopname, DESKTOPNAME); Thread_Desktop(MyThread, (THREAD_DATA *)&td); return TRUE; // 암호키생성 (USB 선택완료 ) 버튼 case IDC_ENCRYPTION: HWND hlist; hlist=getdlgitem(hdlg, IDC_LIST2); i=sendmessage(hlist, LB_GETCURSEL,0,0); SendMessage(hList, LB_GETTEXT, i, (LPARAM)File); if(i<0) MessageBox(hWnd,TEXT("usb를선택해주세요 "),TEXT(" 경고 "),MB_OK); else if(i==0 i==1) MessageBox(hWnd,TEXT("C와 D드라이브를제외한 usb를선택해주세요 "),TEXT(" 경고 "),MB_OK); else WideCharToMultiByte(CP_ACP, 0, File, 260, filetest, 260, NULL, NULL); Remove(filetest); MultiByteToWideChar( CP_ACP, 0, filetest, -1, File, 260); wcscpy(foldercp2, NUL); wcscat(foldercp2, File); wcscat(foldercp2, L":\\BackUp"); //MessageBox(hWnd, FolderCP2,TEXT(" 알림 "),MB_OK); SetDlgItemText(hDlg, IDC_EDIT2, FolderCP2); wcscat(file, (LPCTSTR)Txtname); hfile = CreateFile(File, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, 0); //CREATE_ALWAYS 를OPEN_EXISTING 로수정하면파일끝에추가 // 암호화부분 if(!cryptacquirecontext(&hprov, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0)) //CSP(Crystographic Service Provider) 핸들얻기 CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV,PROV_RSA_FULL, CRYPT_NEWKEYSET); // 유저용키컨테이너만들기 CryptGenRandom(hProv,1,&MY_PASSKEY); // 난수생성 wsprintf((lpwstr)my_passwd,text("%d273%d58%d"),my_passkey,my_passkey,my_passkey); //MessageBox(hWnd, (LPWSTR)MY_PASSWD,TEXT("MY_PASSKEY"),MB_OK); - 16 -
CryptCreateHash(hProv, CALG_SHA, 0, 0, &hhash);// 해쉬만들기 CryptHashData(hHash, (BYTE*)MY_PASSWD,sizeof(MY_PASSWD),0); //(DWORD)strlen(MY_PASSWD), 0); // 해쉬값계산 CryptDeriveKey(hProv, CALG_RC4, hhash, KeyLen, &hkey); // 키만들기CALG_AES_128 CryptEncrypt(hKey, 0, TRUE, 0, pbdata, &dwdatalen, 30);// 암호화 WriteFile(hFile, pbdata, sizeof(pbdata),&result, NULL); //CryptDecrypt(hKey, 0, TRUE, 0, pbdata, &dwdatalen);// 복호화 CryptDestroyKey(hKey); CryptDestroyHash(hHash); // 해쉬없애기 CryptReleaseContext(hProv, 0); // CSP 핸들풀어주기 CloseHandle(hFile); wcscpy(tempname,ctxtname); wcscat(tempname, (LPCTSTR)Txtname); //d 드라이브에파일복사 CopyFile(File,Tempname,false); //d드라이브에파일복사 //wsprintf(usblist,text("%s 파일생성완료 "),File); //MessageBox(hWnd, usblist,text(" 알림 "),MB_OK); return TRUE; // 파일암호화버튼 case IDC_FILE_ENCRYPTION: //MessageBox(hWnd, TEXT(" 파일암호화 "),TEXT(" 메시지박스 "),MB_OK); // 복사하는기능및암호화기능 GetDlgItemText(hDlg, IDC_EDIT,FolderCP,150); if (!lstrlen (FolderCP) ) MessageBox(hWnd,L" 백업폴더를지정해주세요!",L" 알림 ",MB_OK); else GetDlgItemText(hDlg, IDC_EDIT2,FolderCP2,150); if (!lstrlen (FolderCP2) ) MessageBox(hWnd,L"USB를지정해주세요!",L" 알림 ",MB_OK); else CreateDirectory(FolderCP2, NULL); if(xcopy(foldercp, FolderCP2)) MessageBox(hWnd,L" 복사를완료했습니다 ",L" 알림 ",MB_OK); if(fileencryption(foldercp,foldercp2,hdlg)) MessageBox(hWnd,L" 진행중 ",L"FileEncryption",MB_OK); return TRUE; // 파일복호화버튼 case IDC_FILE_DECRYPTION: CreateDirectory(FolderCP, NULL); if(xcopy(foldercp2, FolderCP)) MessageBox(hWnd,L" 복사를완료했습니다 ",L" 알림 ",MB_OK); if(filedecryption(foldercp2,foldercp,hdlg)) MessageBox(hWnd,L" 진행중 ",L"FileDecryption",MB_OK); return TRUE; - 17 -
//... 버튼 case IDC_FINDFORDER: if (BrowseFolder(hWnd,TEXT(" 폴더를선택하세요 "),StartPath,Folder)) SetDlgItemText(hDlg, IDC_EDIT, Folder); return TRUE; // 도움말버튼 case IDC_HELP: DialogBox( g_hinstance, MAKEINTRESOURCE(IDD_Help), HWND_DESKTOP, HelpProc ); return TRUE; // 만든이버튼 MakerProc ); case IDC_MAKER: return TRUE; DialogBox( g_hinstance, MAKEINTRESOURCE(IDD_MAKER), HWND_DESKTOP, case IDCANCEL: EndDialog(hDlg,0); return TRUE; return FALSE; return FALSE; INT_PTR CALLBACK OkProc(HWND hdlg, UINT Message, WPARAM wparam, LPARAM lparam) HDC hdc; PAINTSTRUCT ps; HANDLE hfile; DWORD dwread; RECT rt; switch(message) case WM_PAINT : hdc=beginpaint(hdlg, &ps); GetClientRect(hDlg,&rt); // 텍스트바탕출력을투명으로 ::SetBkMode( hdc, TRANSPARENT ); DrawText(hdc,buf,-1,&rt,DT_WORDBREAK); EndPaint(hDlg, &ps); break - 18 -
case WM_CLOSE : EndDialog( hdlg, 0 ); return FALSE; INT_PTR CALLBACK UnlockEditProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam) int i=0; switch(message) //USB 인식부분 case WM_DEVICECHANGE: switch (LOWORD(wParam)) case DBT_DEVICEARRIVAL: wcscpy(tempname,ctxtname); wcscat(tempname, (LPCTSTR)Txtname); while(1) wcscpy(copytxtname,ftxtname[i]); wcscat(copytxtname,(lpctstr)txtname); if(pathfileexists(copytxtname)) //MessageBox(hWnd, L" 파일있음 ",TEXT(" 확인 "),MB_OK);// 파일있음 R_hFile = CreateFile(copyTxtname, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ReadFile(R_hFile, Rstring, 20, &RRead, NULL); f_hfile = CreateFile(Tempname, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ReadFile(f_hFile, fstring, 20, &RRead, NULL); //MessageBox(hWnd, Rstring, L" 확인 ", MB_OK); //MessageBox(hWnd, fstring, L" 확인 ", MB_OK); if(wcscmp(fstring, Rstring)==0) //MessageBox(hWnd, L" 일치 ",TEXT(" 알림 "),MB_OK); g_bunlock = true CloseHandle(R_hFile); CloseHandle(f_hFile); EndDialog( hwnd, 0 ); break else CloseHandle(R_hFile); CloseHandle(f_hFile); MessageBox(hWnd, L" 암호불일치 ", L" 오류 ", MB_OK); break - 19 -
break else // 파일없음 i++; if(i==6)i=0; MessageBox(hWnd, L" 파일없음 ", L" 오류 ", MB_OK); break break case DBT_DEVICEREMOVECOMPLETE: g_bunlock = false break default: break return TRUE; return 0; return FALSE; INT_PTR CALLBACK HelpProc(HWND hdlg, UINT Message, WPARAM wparam, LPARAM lparam) HDC hdc; PAINTSTRUCT ps; HANDLE hfile; DWORD dwread; RECT rt; switch(message) case WM_INITDIALOG : hfile = CreateFile(L"help.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hfile!= INVALID_HANDLE_VALUE) ZeroMemory( buf, sizeof(buf) ); ::ReadFile(hFile, buf, sizeof(buf), &dwread, NULL); CloseHandle(hFile); return 0; case WM_PAINT : hdc=beginpaint(hdlg, &ps); GetClientRect(hDlg,&rt); // 텍스트바탕출력을투명으로. ::SetBkMode( hdc, TRANSPARENT ); DrawText(hdc,buf,-1,&rt,DT_WORDBREAK); EndPaint(hDlg, &ps); break - 20 -
case WM_CLOSE : EndDialog( hdlg, 0 ); return FALSE; INT_PTR CALLBACK MakerProc(HWND hdlg, UINT Message, WPARAM wparam, LPARAM lparam) HDC hdc; PAINTSTRUCT ps; HANDLE hfile; DWORD dwread; RECT rt; switch(message) case WM_INITDIALOG : hfile = CreateFile(L"Maker.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hfile!= INVALID_HANDLE_VALUE) ZeroMemory( buf, sizeof(buf) ); ::ReadFile(hFile, buf, sizeof(buf), &dwread, NULL); CloseHandle(hFile); return 0; case WM_PAINT : hdc=beginpaint(hdlg, &ps); GetClientRect(hDlg,&rt); // 텍스트바탕출력을투명으로. ::SetBkMode( hdc, TRANSPARENT ); DrawText(hdc,buf,-1,&rt,DT_WORDBREAK); EndPaint(hDlg, &ps); break case WM_CLOSE : EndDialog( hdlg, 0 ); return FALSE; - 21 -
// 경로설정 #include <shlobj.h> int CALLBACK BrowseCallbackProc(HWND hwnd,uint umsg,lparam lparam,lparam lpdata) switch (umsg) case BFFM_INITIALIZED: if (lpdata!= NULL) SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)lpData); break return 0; BOOL BrowseFolder(HWND hparent, LPCTSTR sztitle, LPCTSTR StartPath, TCHAR *szfolder) LPMALLOC pmalloc; LPITEMIDLIST pidl; BROWSEINFO bi; bi.hwndowner = hparent; bi.pidlroot = NULL; bi.pszdisplayname = NULL; bi.lpsztitle = sztitle ; bi.ulflags = 0; bi.lpfn = BrowseCallbackProc;; bi.lparam = (LPARAM)StartPath; pidl = SHBrowseForFolder(&bi); if (pidl == NULL) return FALSE; SHGetPathFromIDList(pidl, szfolder); if (SHGetMalloc(&pMalloc)!= NOERROR) return FALSE; pmalloc->free(pidl); pmalloc->release(); return TRUE; // 문자열 "[-" "-]" 제거 char Remove(char* in_hasgenre) char *bp, *tp; bp = in_hasgenre; tp = in_hasgenre + strlen(in_hasgenre); - 22 -
// 전방으로 "[-" 제거처리 while ( *bp!= '\0' && (*bp == '[' *bp == '-' (unsigned char)(*bp) <= 0x20 ) ) bp++; // 후방으로 "-]" 제거처리 while ( tp >= in_hasgenre && (*tp == ']' *tp == '-' (unsigned char)(*tp) <= 0x20) ) tp--; *(tp+1) = '\0' tp = in_hasgenre; while ( *bp!= '\0' ) if ( *bp == ' ' *bp == '-' ) bp++; continue *tp = *bp; tp++; bp++; *tp = '\0' return *in_hasgenre; // 폴더복사 // XCopy(Dir1, Dir2) 형태로사용한다. 1>2 BOOL XCopy(LPCTSTR Src, LPCTSTR Dest) HANDLE hsrch; WIN32_FIND_DATA wfd; BOOL bresult=true; TCHAR WildCard[MAX_PATH]; TCHAR SrcFile[MAX_PATH]; TCHAR DestFile[MAX_PATH]; wsprintf(wildcard,l"%s\\*.*",src); CreateDirectory(Dest,NULL); hsrch=findfirstfile(wildcard,&wfd); if (hsrch == INVALID_HANDLE_VALUE) return FALSE; while (bresult) wsprintf(srcfile,l"%s\\%s",src,wfd.cfilename); wsprintf(destfile,l"%s\\%s",dest,wfd.cfilename); // 서브디렉토리가발견되면서브디렉토리를복사한다. if (wfd.dwfileattributes & FILE_ATTRIBUTE_DIRECTORY) if (lstrcmp(wfd.cfilename,l".") && lstrcmp(wfd.cfilename,l"..")) XCopy(SrcFile, DestFile); else CopyFile(SrcFile,DestFile,FALSE); bresult=findnextfile(hsrch,&wfd); FindClose(hSrch); return TRUE; - 23 -
BOOL FileEncryption(LPCTSTR Src, LPCTSTR Dest,HWND hwnd) //, LPCTSTR Dest) // Foldercp FolderCP2가들어와야함 HANDLE hsrch; HANDLE hfile; BOOL bresult=true; WIN32_FIND_DATA wfd; // BOOL bresult; TCHAR WildCard[MAX_PATH]; TCHAR findfirstfilename[max_path]; TCHAR findsecondfilename[max_path]; DWORD result; DWORD tlen; BYTE PASSWD[100]="TEST" TCHAR buf[16]=0,; int poin = 0; int point; wsprintf(wildcard,l"%s\\*.*",src); hsrch=findfirstfile(wildcard,&wfd); MessageBox(hwnd, WildCard, L"WildCard", MB_OK); if (hsrch == INVALID_HANDLE_VALUE) return FALSE; while (bresult) wsprintf(findfirstfilename,l"%s\\%s",src,wfd.cfilename); wsprintf(findsecondfilename,l"%s\\%s",dest,wfd.cfilename); if (wfd.dwfileattributes & FILE_ATTRIBUTE_DIRECTORY) if (lstrcmp(wfd.cfilename,l".") && lstrcmp(wfd.cfilename,l"..")) XCopy(findFirstFileName, findsecondfilename); hfile = CreateFile(findSecondFileName, GENERIC_WRITE GENERIC_READ, FILE_SHARE_WRITE FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ReadFile(hFile, buf, sizeof(buf),&result, NULL); SetFilePointer(hFile, 0, NULL, FILE_BEGIN); // 파일포인터를파일의처음으로이동 tlen=lstrlen(buf); CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); - 24 -
//CSP(Crystographic Service Provider) 핸들얻기 CryptCreateHash(hProv, CALG_SHA, 0, 0, &hhash);// 해쉬만들기 CryptHashData(hHash, (BYTE*)PASSWD,sizeof(PASSWD),0);// 해쉬값계산 CryptDeriveKey(hProv, CALG_RC4, hhash, KeyLen, &hkey); // 키만들기CALG_AES_128 CryptEncrypt(hKey, 0, TRUE, 0, (BYTE *)buf, &dwdatalen, sizeof(buf));// 암호화 CryptDestroyKey(hKey); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); WriteFile(hFile, buf, sizeof(tlen),&result, NULL); //for(int i=0;i<8;i++) buf[i]=0; CloseHandle(hFile); // 파일닫기 hfile = CreateFile(L"ok.txt", GENERIC_READ GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, buf, sizeof(tlen), &result, NULL); for(int i=0;i<16;i++) buf[i]=0; CloseHandle(hFile); else sprintf( (char*)my_passwd, "TestPassword" ); CopyFile(findFirstFileName,findSecondFileName,FALSE); CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); //CSP(Crystographic Service Provider) 핸들얻기 CryptCreateHash(hProv, CALG_SHA, 0, 0, &hhash);// 해쉬만들기 CryptHashData(hHash, (BYTE*)MY_PASSWD,sizeof(MY_PASSWD),0);// 해쉬값계산 CryptDeriveKey(hProv, CALG_RC4, hhash, KeyLen, &hkey); // 키만들기 CALG_AES_128 FileEncryption( findfirstfilename, findsecondfilename, hkey ); CryptDestroyKey(hKey); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); //CloseHandle(hFile); hfile = CreateFile(L"F:\ok.txt", GENERIC_READ GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, buf, sizeof(tlen), &result, NULL); for(int i=0;i<16;i++) buf[i]=0; CloseHandle(hFile); // bresult=findnextfile(hsrch,&wfd); - 25 -
// 암호화부분 //CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); //CSP(Crystographic Service Provider) 핸들얻기 // CryptCreateHash(hProv, CALG_SHA, 0, 0, &hhash);// 해쉬만들기 // CryptHashData(hHash, (BYTE*)PASSWD,sizeof(PASSWD),0);//(DWORD)strlen(PASSWD), 0); // 해쉬값계산 // CryptDeriveKey(hProv, CALG_RC4, hhash, KeyLen, &hkey); // 키만들기CALG_AES_128 // CryptEncrypt(hKey, 0, TRUE, 0, (BYTE *)buf, &dwdatalen, sizeof(buf));// 암호화 // CryptDecrypt(hKey, 0, TRUE, 0, pbdata, &dwdatalen);// 복호화 // CryptDestroyKey(hKey); // CryptDestroyHash(hHash); // 해쉬없애기 // CryptReleaseContext(hProv, 0); // CSP 핸들풀어주기 FindClose(hSrch); return TRUE; BOOL FileDecryption(LPCTSTR Src, LPCTSTR Dest,HWND hwnd) //, LPCTSTR Dest) // Foldercp FolderCP2가들어와야함 HANDLE hsrch; HANDLE hfile; BOOL bresult=true; WIN32_FIND_DATA wfd; // BOOL bresult; TCHAR WildCard[MAX_PATH]; TCHAR findfirstfilename[max_path]; TCHAR findsecondfilename[max_path]; DWORD result; DWORD tlen; BYTE PASSWD[100]="TEST char buf[16]=0,; TCHAR dbuf[16]=0,; int poin = 0; int point; TCHAR name[max_path]; wsprintf(wildcard,l"%s\\*.*",dest); hsrch=findfirstfile(wildcard,&wfd); MessageBox(hwnd, WildCard, L"WildCard", MB_OK); - 26 -
if (hsrch == INVALID_HANDLE_VALUE) return FALSE; while (bresult) wsprintf(findfirstfilename,l"%s\\%s",src,wfd.cfilename); wsprintf(findsecondfilename,l"%s\\%s",dest,wfd.cfilename); if (wfd.dwfileattributes & FILE_ATTRIBUTE_DIRECTORY) if (lstrcmp(wfd.cfilename,l".") && lstrcmp(wfd.cfilename,l"..")) hfile = CreateFile(findSecondFileName, GENERIC_WRITE GENERIC_READ, FILE_SHARE_WRITE FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ReadFile(hFile, buf, sizeof(buf),&result, NULL); 파일의처음으로이동 SetFilePointer(hFile, 0, NULL, FILE_BEGIN); // 파일포인터를 WriteFile(hFile, buf, sizeof(tlen),&result, NULL); //for(int i=0;i<8;i++) buf[i]=0; CloseHandle(hFile); // 파일닫기 hfile = CreateFile(L"F:\okk.txt", GENERIC_READ GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, buf, sizeof(tlen), &result, NULL); for(int i=0;i<16;i++) buf[i]=0; CloseHandle(hFile) else sprintf( (char*)my_passwd, "TestPassword" ); //for(int i=0; i<4; i++) // //point = i*4+poin; //hfile = CreateFile(findSecondFileName, GENERIC_WRITE GENERIC_READ, FILE_SHARE_WRITE FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); //ZeroMemory( buf, sizeof(buf) ); //SetFilePointer(hFile, point, NULL, FILE_BEGIN); // 파일포인터를파일의처음으로이동 //ReadFile(hFile, buf, 16,&result, NULL); //WideCharToMultiByte(CP_ACP, NULL, buf, -1, cbuf, 16, NULL, FALSE); CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); //CSP(Crystographic Service Provider) 핸들얻기 CryptCreateHash(hProv, CALG_SHA, 0, 0, &hhash); // 해쉬만들기 CryptHashData(hHash, (BYTE*)MY_PASSWD,sizeof(MY_PASSWD),0); // 해쉬값계산 CryptDeriveKey(hProv, CALG_RC4, hhash, KeyLen, &hkey); // 키만들기CALG_AES_128-27 -
FileEncryption(findFirstFileName, findsecondfilename, hkey ); CryptDestroyKey(hKey); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); /*try char szhex[33]; //One block testing CRijndael orijndael; orijndael.makekey("abcdefghabcdefgh", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 16); char szdataout[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; orijndael.decryptblock(buf, szdataout); //CharStr2HexStr((unsigned char*)cbuf, szhex, 16); MultiByteToWideChar(CP_ACP, 0, szdataout, -1, dbuf, strlen(szdataout)); //MultiByteToWideChar(CP_UTF8, NULL, szdataout, -1, buf, 16); SetFilePointer(hFile, point, NULL, FILE_BEGIN); WriteFile(hFile, dbuf, sizeof(tlen),&result, NULL); catch(exception& roexception) cout << roexception.what() << endl; CloseHandle(hFile);*/ hfile = CreateFile(L"F:\okk.txt", GENERIC_READ GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, buf, sizeof(tlen), &result, NULL); for(int i=0;i<16;i++) buf[i]=0; CloseHandle(hFile); // bresult=findnextfile(hsrch,&wfd); FindClose(hSrch); return TRUE; // CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); //CSP(Crystographic Service Provider) 핸들얻기 //CryptCreateHash(hProv, CALG_SHA, 0, 0, &hhash);// 해쉬만들기 //CryptHashData(hHash, (BYTE*)PASSWD,sizeof(PASSWD),0);// 해쉬값계산 //CryptDeriveKey(hProv, CALG_RC4, hhash, KeyLen, &hkey); // 키만들기CALG_AES_128 //CryptImportKey( hprov, (BYTE *)enckey, length, rsakey, CRYPT_EXPORTABLE, &aeskey ); // CryptImportKey( hprov, (BYTE *)PASSWD, sizeof(passwd), NULL, 0, &hkey ); //CryptGenKey( hprov, CALG_AES_128,hHash,&hKey); // CryptEncrypt(hKey, 0, TRUE, 0, (BYTE *)buf, &dwdatalen, sizeof(buf));// 암호화 // CryptDestroyKey(hKey); //CryptDestroyHash(hHash); // CryptReleaseContext(hProv, 0); - 28 -
Ⅲ. 결론 Ⅲ-1. 기대효과 본프로그램의화면잠금기능을적절히사용할경우인가받지않은타인이고의성을갖고악의적인목적으로 PC를사용하고자접근을시도하여도프로그램을완전히종료하기전에는닫히지않는구조이기때문에작성중인문서를비롯한 PC 내의모든개인정보를보호할수있습니다. 단 PC의 Boot 메뉴나사용자패스워드가설정되어있지않은경우에는재부팅후여전히위협에노출되어있기때문에기본적인패스워드설정이선행되어야합니다. 특정폴더를지정하여해당폴더안의파일들을암호화한후백업하는기능의경우 USB는휴대성과경량이라는장점이있지만분실후의자료에대한보안은전혀유지되지않으므로분실의우려와분실시내부의정보가전혀보호되지않는다는위험이항상존재하기때문에보안이요구되는자료가저장되어있을경우특히적절히사용할수있다고판단되어기능을탑재하였습니다. Ⅲ-2. 프로그램의향후발전, 개선방향 1. 현재 (2015. 5. 13) 화면잠금기능에대하여 Window이외의다른운영체제에서는동작이확인되지않습니다. 이는윈도우의 C++ 기반으로코딩되었기때문이며추후기회가생긴다면 vim이나 Shell 코드등을이용하여 Linux 커널에서도동작이가능하도록제작을고려하고있습니다. 2. 현재백업기능의암호화옵션은백업할폴더내의 *.txt 파일로만한정되어있습니다. 한컴 Office의 *.hwp나 Microsoft Office의 *.doc 파일은문서의 Read 방식이일반 *.txt 파일과다소상이한부분이존재하여인식하지못하고있습니다. 이또한기회가주어진다면더욱다양한확장자를지닌파일에대하여암호화가가능하도록함이목표입니다. 3. 프로그램실행화면의레이아웃디자인부분은시제품 (v 1.0.0) 으로제작되어프로그램 자체의 IDD 파일을사용하였습니다. Free Permission UI 와 Button, Menu 등을사용하여 가독성을높이는등 Visual 적인측면을고려하여재디자인할예정입니다. - 29 -
Ⅳ. 참고자료 Ⅳ-1. 참고알고리즘, 블로그및사건, 사고사례 Windows API https://ko.wikipedia.org/wiki/%ec%9c%88%eb%8f%84_api DLL https://ko.wikipedia.org/wiki/%eb%8f%99%ec%a0%81_%eb%a7%81%ed%81%ac_%eb%9d%bc%ec%9d%b4 %EB%B8%8C%EB%9F%AC%EB%A6%AC SK Communications 정보유출사건 https://mirror.enha.kr/wiki/sk%ec%bb%b4%ec%a6%88%20%ea%b0%9c%ec%9d%b8%ec%a0%95%eb%b3% B4%20%EC%9C%A0%EC%B6%9C%20%EC%82%AC%EA%B1%B4 카드 3사개인정보유출사건 http://ko.wikipedia.org/wiki/2014%eb%85%84_%eb%8c%80%ed%95%9c%eb%af%bc%ea%b5%ad_%ea%b0 %9C%EC%9D%B8%EC%A0%95%EB%B3%B4_%EB%8C%80%EB%9F%89%EC%9C%A0%EC%B6%9C_%EC%82%AC %EA%B1%B4 AES 알고리즘 http://ko.wikipedia.org/wiki/%ea%b3%a0%ea%b8%89_%ec%95%94%ed%98%b8%ed%99%94_%ed%91%9c% EC%A4%80 참고자료 ( 블로그 ) http://www.mimul.com/pebble/default/2009/02/27/1235731380000.html http://lyb1495.tistory.com/25 Hash 함수 http://ko.wikipedia.org/wiki/%ed%95%b4%ec%8b%9c_%ed%95%a8%ec%88%98 Screen Lock http://en.wikipedia.org/wiki/lock_screen - 30 -
Ⅴ. 별첨 Ⅴ-1. 발표 PPT ----------------------------------------------------------------------------- - 31 -
----------------------------------------------------------------------------- - 32 -
----------------------------------------------------------------------------- - 33 -
----------------------------------------------------------------------------- - 34 -
----------------------------------------------------------------------------- - 35 -
----------------------------------------------------------------------------- - 36 -
----------------------------------------------------------------------------- - 37 -
----------------------------------------------------------------------------- - 38 -