Win32のDPAPIをC++/ATLで使用するサンプルがあまりないので公開。
DPAPIを使用すると、システムがWindowsのユーザープロファイルから暗号鍵を生成するため、アプリケーションはキーの管理をすることなくデータの暗号化が可能です。
dwFlagsにCRYPTPROTECT_LOCAL_MACHINEを指定すると、ユーザーではなくシステムプロファイルで解読可能となります。
CAtlArray<BYTE> cypherBytes;
CryptDPAPI::Encrypt(L"DPAPI sample", cypherBytes);
CString strPlain = CryptDPAPI::Decrypt(cypherBytes);
#pragma once #pragma comment(lib, "Crypt32.lib") #include "stdafx.h" #include <Wincrypt.h> #include <atlcoll.h> #include <atlstr.h> class CryptDPAPI { public: static DWORD Encrypt(LPCTSTR szSource, CAtlArray<BYTE> &result, LPCTSTR szDescription = L"", DWORD dwFlags = 0L) { DATA_BLOB plainData; DATA_BLOB cypherData = {0}; plainData.pbData = (BYTE *)szSource; plainData.cbData = (lstrlen(szSource)+1) * sizeof(TCHAR); if(CryptProtectData(&plainData, szDescription, NULL, NULL, NULL, dwFlags, &cypherData)) { result.SetCount(cypherData.cbData); ::CopyMemory(&result[0], cypherData.pbData, cypherData.cbData); LocalFree(cypherData.pbData); return cypherData.cbData; } return 0L; } static CString Decrypt(CAtlArray<BYTE> &cypherBytes, LPTSTR *pszDescription = NULL, DWORD dwFlags = 0L) { return Decrypt(&cypherBytes[0], cypherBytes.GetCount(), pszDescription, dwFlags); } static CString Decrypt(BYTE *pCypherBytes, DWORD count, LPTSTR *pszDescription = NULL, DWORD dwFlags = 0L) { DATA_BLOB cypherData; DATA_BLOB plainData = {0}; cypherData.pbData = pCypherBytes; cypherData.cbData = count; if (CryptUnprotectData(&cypherData, pszDescription, NULL, NULL, NULL, dwFlags, &plainData)) { CString strResult; strResult = (LPTSTR)plainData.pbData; LocalFree(plainData.pbData); return strResult; } } };
おかしなところなどあれば乞ご指摘。