いつもお世話になっております。Kettyです(^▽^)
Windows標準の暗号化関数CryptProtectDataおよびCryptUnprotectDataを使って、
文字列の暗号化/複合したいのですが、複合に失敗します。
なぜ失敗するのか理解できないので、どこに誤りがあるか教えてください。
【環境】
Windows7 Home Edition 64bit
Visual Studio 2010 Express Edition
C++(stl)とDXライブラリを使用しています。
【参考にした記事】
http://eternalwindows.jp/crypto/dpapi/dpapi02.html
http://msdn.microsoft.com/ja-jp/library ... s.85).aspx
http://msdn.microsoft.com/ja-jp/library ... s.85).aspx
http://owlsperspective.blogspot.jp/2010 ... art-1.html
https://msmania.wordpress.com/tag/cryptprotectdata/
【ソース】
#include <Windows.h>
#include <string>
#include <DxLib.h>
// 暗号化用
#pragma comment(lib, "crypt32.lib")
using namespace std;
// 文字列を暗号化する(または複合する) 第1引数trueで暗号化, falseで複合
bool CryptText( const bool & isEncryptMode, const string & in_text, string & out_text )
{
// 戻り値クリア
out_text.clear() ;
// 入力が空なら処理しない
if( in_text.empty() ){ return false ; }
DATA_BLOB blobIn ; // 入力データ
DATA_BLOB blobOut ; // 出力データ
// 入力データ生成
blobIn.cbData = in_text.size() ;
blobIn.pbData = (LPBYTE)in_text.c_str() ;
// 暗号化する
if( isEncryptMode )
{
// パスワード入力のプロンプトを表示させずローカルコンピュータの全ユーザーが複合可能とする
if( CryptProtectData( &blobIn, NULL, NULL, NULL, NULL, ( CRYPTPROTECT_UI_FORBIDDEN | CRYPTPROTECT_LOCAL_MACHINE ), &blobOut ) == FALSE )
{
return false ; // 失敗
}
}
// 複合する
else
{
// パスワード入力のプロンプトを表示させない
if( CryptUnprotectData( &blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut ) == FALSE )
{
return false ; // 失敗 ※ここで必ず失敗する( GetLastError()によると、"パラメーターが間違っています。" )
}
}
// 戻り値に暗号化後(または複合後)の文字列をセット
out_text = reinterpret_cast<const char *>( &blobOut.pbData ) ;
// 解放
SecureZeroMemory( blobOut.pbData, blobOut.cbData ) ;
LocalFree( blobOut.pbData ) ;
return true ;
}
// Main関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// DXライブラリのログ出力をしない
DxLib::SetOutApplicationLogValidFlag( FALSE ) ;
// ウィンドウモードで起動
DxLib::ChangeWindowMode( TRUE ) ;
// 画面モード設定
DxLib::SetGraphMode( 640, 480, 32 ) ;
// DXライブラリ初期化処理
if( DxLib::DxLib_Init() == -1 ){ return -1 ; }
// フォント設定
const int fontHandle = DxLib::CreateFontToHandle( "メイリオ", 20, DX_FONTTYPE_ANTIALIASING ) ;
const int fontColor = DxLib::GetColor( 255, 255, 255 ) ;
// プレーン文字列
const string planeText = "This is a pen." ;
// 暗号化する
string encryptText ;
bool isEncryptSuccess = CryptText( true, planeText, encryptText ) ;
// 複合化する
string decryptText ;
bool isDencryptSuccess = CryptText( false, encryptText, decryptText ) ;
// メインループ(ESCで終了)
while( DxLib::ProcessMessage() == 0 && DxLib::CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
// 画面クリア
DxLib::ClsDrawScreen();
// プレーン文字列を描画
DxLib::DrawStringToHandle( 100, 100, ( "planeText=" + planeText ).c_str(), fontColor, fontHandle ) ;
// 暗号化した文字列を描画
DxLib::DrawStringToHandle( 100, 150, ( "encryptText=" + encryptText ).c_str(), fontColor, fontHandle ) ;
// 複合後の文字列を描画
DxLib::DrawStringToHandle( 100, 200, ( "decryptText=" + decryptText ).c_str(), fontColor, fontHandle ) ;
// 暗号化失敗したとき
if( isEncryptSuccess == false )
{
DxLib::DrawStringToHandle( 20, 250, "Encrypt error!", fontColor, fontHandle ) ;
}
// 複合に失敗したとき
if( isDencryptSuccess == false )
{
DxLib::DrawStringToHandle( 20, 300, "Decrypt error!", fontColor, fontHandle ) ;
}
// しばらく待つ
Sleep( 10 ) ;
}
// DXライブラリ終了処理
DxLib::DxLib_End() ;
// ソフトの終了
return 0 ;
}
また、デバッガでステップ実行すると、CryptUnprotectDataがFALSEを返し、失敗していることを確認ています。
GetLastError()でエラーメッセージを取得したところ、"パラメーターが間違っています。"となることを確認しています。
追記※上記エラーメッセージが誤っていたので修正しました。
よろしくお願いします。