본문 바로가기
Programming/3. MFC

파일을 암호화 / 복호화 하기

by S.W 2022. 12. 1.

◆ 윈도우즈 API를 이용하여 파일 암호화하기

#include <io.h>                // 파일관련
#include <WinCrypt.h>        // 암호화

      :
// 암호화 버튼을 클릭했을 때
void CCiperFileDlg::OnBnClickedEncode()
{
    BYTE    *bBuff;
    DWORD    dwFileLen;
    CString    csFile;
    FILE    *pFile;

    m_File.GetWindowText(csFile);

    // 선택한 파일을 바이너리 형식으로 열기
    pFile = fopen(csFile, "rb");
    if(!pFile)
    {
        AfxMessageBox("파일읽을때 에러났어");
        return;
    }

    dwFileLen = _filelength(fileno(pFile));
    bBuff = new BYTE [dwFileLen];

    // 파일 읽어서 버퍼에 저장
    fread(bBuff, 1, dwFileLen, pFile);
    fclose(pFile);

    HCRYPTPROV    hProv;
    HCRYPTHASH    hHash;
    HCRYPTKEY    hKey;
    CString        csPass;

    m_Pass.GetWindowText(csPass);

    // 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))
        {
            AfxMessageBox("암호화 실패야");
            return;
        }
    }

    // 해쉬 만들기
    CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
    // 해쉬 값 계산
    CryptHashData(hHash, (BYTE*)(LPCTSTR)csPass, csPass.GetLength(), 0);
    // 키 만들기\tab
    CryptDeriveKey(hProv, CALG_RC4, hHash, 0x0080*0x10000, &hKey);
    // 암호화\tab
    CryptEncrypt(hKey, 0, TRUE, 0, bBuff, &dwFileLen, dwFileLen);
    // 해쉬 없애기
    CryptDestroyHash(hHash);
    // CSP 핸들 풀어주기
    CryptReleaseContext(hProv, 0);

    csFile += ".CPR";

    // 파일저장 윈도우 표시
    CFileDialog    fDlg(FALSE, "", csFile);

    if(fDlg.DoModal() == IDOK)
    {
        // 암호화된 파일 저장하기
        pFile = fopen(fDlg.GetPathName(), "wb");
        fwrite(bBuff, 1, dwFileLen, pFile);
        fclose(pFile);
    }

    // 버퍼 삭제
    delete [] bBuff;
}



◆ 윈도우즈 API를 이용하여 파일 복호화하기

// 복호화 버튼을 클릭했을 때
void CCiperFileDlg::OnBnClickedDecode()
{
    BYTE    *bBuff;
    DWORD    dwFileLen;
    CString    csFile;
    FILE    *pFile;

    m_File.GetWindowText(csFile);

    // 선택한 파일을 바이너리 형식으로 열기
    pFile = fopen(csFile, "rb");
    if(!pFile)
    {
        AfxMessageBox("파일읽을때 에러났어");
        return;
    }

    dwFileLen = _filelength(fileno(pFile));
    bBuff = new BYTE [dwFileLen];

    // 파일 읽어서 버퍼에 저장
    fread(bBuff, 1, dwFileLen, pFile);
    fclose(pFile);

    HCRYPTPROV    hProv;
    HCRYPTHASH    hHash;
    HCRYPTKEY    hKey;
    CString        csPass;

    m_Pass.GetWindowText(csPass);

    // 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))
        {
            AfxMessageBox("복호화 실패야");
            return;
        }
    }

    // 해쉬 만들기
    CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
    // 해쉬 값 계산
    CryptHashData(hHash, (BYTE*)(LPCTSTR)csPass, csPass.GetLength(), 0);
    // 키 만들기\tab
    CryptDeriveKey(hProv, CALG_RC4, hHash, 0x0080*0x10000, &hKey);
    // 복호화
    CryptDecrypt(hKey, 0, TRUE, 0, bBuff, &dwFileLen);
    // 해쉬 없애기
    CryptDestroyHash(hHash);
    // CSP 핸들 풀어주기
    CryptReleaseContext(hProv, 0);

    // 파일저장 윈도우 표시
    CFileDialog    fdlg(FALSE, "", csFile);

    if(fdlg.DoModal() == IDOK)
    {
        // 복호화된 파일 저장하기
        pFile = fopen(fdlg.GetPathName(), "wb");
        fwrite(bBuff, 1, dwFileLen, pFile);
        fclose(pFile);
    }

    // 버퍼 삭제
    delete [] bBuff;
}