RC4를 통한 데이터 암호화 해독

#ifndef CRYPOTRC4_H
#define CRYPOTRC4_H

#include <afxwin.h>
#include <atlcoll.h>
#include <wincrypt.h>

class CCryptoRC4 : CObject
{
public:
	enum CryptoType
	{
		/// <summary>    </summary>
		Unknown = 0,

		/// <summary>    </summary>
		Encrypted = 1,

		/// <summary>    </summary>
		Decrypted = 2
	};
public:
	CCryptoRC4(const TCHAR* szPassword)
	{
		Initialization((BYTE*) szPassword, (DWORD) (_tcslen(szPassword) * sizeof(TCHAR)));
	}

	CCryptoRC4(const BYTE* pbPassword, DWORD cbPassword)
	{
		Initialization(pbPassword, cbPassword);
	}

	~CCryptoRC4()
	{
		if (m_hCryptProv)
			CryptReleaseContext(m_hCryptProv, 0);
		if (m_hCryptHash)
			CryptDestroyHash(m_hCryptHash);
		if (m_hCryptKey)
			CryptDestroyKey(m_hCryptKey);
	}

	/// <summary>  RC4      </summary>
	/// <param name="szPlaintext">          </param>
	/// <return>       (  BYTE*)</return>
	const TCHAR* Encrypt(const TCHAR* szPlaintext)
	{
		size_t cbPlaintext = _tcslen(szPlaintext) * sizeof(TCHAR);
		Encrypt((BYTE*) szPlaintext, (DWORD) cbPlaintext);
		for (int i = 0; i < (int) sizeof(TCHAR); i++)
			m_baCiphertext.Add(0);

		return reinterpret_cast<TCHAR*>(m_baCiphertext.GetData());
	}

	/// <summary>  RC4      </summary>
	/// <param name="pbPlaintext">       </param>
	/// <param name="cbPlaintext">         </param>
	/// <return>       (  TCHAR*)</return>
	void Encrypt(const BYTE* pbPlaintext, DWORD cbPlaintext)
	{
		if (!m_baCiphertext.IsEmpty()) m_baCiphertext.RemoveAll();
		m_baCiphertext.SetCount(cbPlaintext); //         

		memcpy_s(m_baCiphertext.GetData(), cbPlaintext, pbPlaintext, cbPlaintext);

		m_lastCryptoType = CryptEncrypt(m_hCryptKey, NULL, TRUE, 0, m_baCiphertext.GetData(),
			&cbPlaintext, cbPlaintext) ? Encrypted : Unknown;
	}

	/// <summary>  RC4      </summary>
	/// <param name="szCiphertext">          </param>
	/// <return>       (  BYTE*)</return>
	const TCHAR* Decrypt(const TCHAR* szCiphertext)
	{
		size_t cbCiphertext = _tcslen(szCiphertext) * sizeof(TCHAR);
		Decrypt((BYTE *)szCiphertext, (DWORD)cbCiphertext);
		for (int i = 0; i < (int) sizeof(TCHAR); i++)
			m_baPlaintext.Add(0);

		return reinterpret_cast<TCHAR*>(m_baPlaintext.GetData());
	}

	/// <summary>  RC4      </summary>
	/// <param name="pbCiphertext">       </param>
	/// <param name="cbCiphertext">         </param>
	/// <return>       (  TCHAR*)</return>
	void Decrypt(const BYTE* szCiphertext, DWORD cbCiphertext)
	{
		if (!m_baPlaintext.IsEmpty()) m_baPlaintext.RemoveAll();
		m_baPlaintext.SetCount(cbCiphertext); //         

		memcpy_s(m_baPlaintext.GetData(), cbCiphertext, szCiphertext, cbCiphertext);

		m_lastCryptoType = CryptDecrypt(m_hCryptKey, 0, TRUE, 0, m_baPlaintext.GetData(),
			&cbCiphertext) ? Decrypted : Unknown;
	}

	/// <summary>          </summary>
	/// <return>             </return>
	ATL::CAtlArray<BYTE>& GetCryptoData()
	{
		return GetCryptoData(m_lastCryptoType);
	}

	/// <summary>           </summary>
	/// <param name="tyCryptoType">       </param>
	/// <return>             </return>
	ATL::CAtlArray<BYTE>& GetCryptoData(CryptoType tyCryptoType)
	{
		if (tyCryptoType == Encrypted) return m_baCiphertext;
		if (tyCryptoType == Decrypted) return m_baPlaintext;

		AfxThrowInvalidArgException();
	}
private:
	/// <summary>        </summary>
	CCryptoRC4(const CCryptoRC4&)
	{
	}

	/// <summary>        </summary>
	void operator =(const CCryptoRC4&)
	{
	}

	/// <summary>RC4       </summary>
	/// <param name="pbPassword">RC4      </param>
	/// <param name="cbPassword">RC4        </param>
	void Initialization(const BYTE* pbPassword, DWORD cbPassword)
	{
		m_hCryptProv = NULL, m_hCryptHash = NULL, m_hCryptKey = NULL;
                m_lastCryptoType = Unknown;

		// Get a handle to user default provider.
		CryptAcquireContext(&m_hCryptProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
		CryptCreateHash(m_hCryptProv, CALG_SHA, 0, 0, &m_hCryptHash);
		CryptHashData(m_hCryptHash, pbPassword, cbPassword, 0);
		CryptDeriveKey(m_hCryptProv, CALG_RC4, m_hCryptHash, CRYPT_EXPORTABLE, &m_hCryptKey);
	}
private:
	/// <summary>         </summary>
	ATL::CAtlArray<BYTE> m_baPlaintext;

	/// <summary>         </summary>
	ATL::CAtlArray<BYTE> m_baCiphertext;

	/// <summary>        </summary>
	CryptoType m_lastCryptoType;

	/// <summary>          </summary>
	HCRYPTPROV m_hCryptProv;

	/// <summary>           </summary>
	HCRYPTHASH m_hCryptHash;

	/// <summary>         </summary>
	HCRYPTKEY m_hCryptKey;
};

#endif // CRYPOTRC4_H

좋은 웹페이지 즐겨찾기