ファイルのシリアル化時に簡単な暗号化を行いたい。 

[戻る]
ハルキ 2010/05/28(金) 11:36:19
質問というより、意見が欲しくて書き込みします。

ファイルの入出力をシリアル化で簡単に行いたいと思っています。
主にCStringの文字列を複数、1ファイルに書き込み読込みしたいのですが、
出力ファイルを、簡単にエディタなどで、開かれて内容を読まれたくありません。
理由は、ユーザ記述のコメントやユーザ情報を含むためです。

そのため、出力時に簡単な暗号化(本当に簡単なレベル)でを行いたいと思います。
今、自分が考えているのは、GetBuffer()で、各1文字単位に定数値を加算、読込み時は
その逆を行って実装しようと考えています。 ↓のコードのような感じになります。

今までの経験で、ファイルの出力時(シリアル化)に暗号化を実装したこと
がある人がいましたら、もっと効率がいい方法や、面白いアイデアなどありましたら
ご教授ねがいたいと思います。


---------------------------------------------------------------------------
CFile cFile;
//書き込み
BOOL bRet = cFile.Open( _T("C:\\test.txt"),CFile::modeCreate | 
CFile::modeWrite);
CArchive ar( &cFile, CArchive::store);

//読込み
//BOOL bRet = cFile.Open( _T("C:\\test.txt"),CFile::modeRead);
//CArchive ar( &cFile, CArchive::load);

CString strBuf = _T("あいうえお");

//書き込み
if( !ar.IsLoading() ){    
    TCHAR* p = strBuf.GetBuffer();
    while( *p != NULL ) {
        short sVal = (short)*p;
        if( *p > 0x7fff)    *p -= 0x7fff;
        else                *p += 0x7fff;
        p++;
    }
    ar << strBuf;
}
//読み込み
else {
    ar >> strBuf;
    TCHAR* p = strBuf.GetBuffer();
    while( *p != NULL ) {
        if( *p > 0x7fff)    *p -= 0x7fff;
        else                *p += 0x7fff;
        p++;
    }
    _tprintf(_T("%s \n"),strBuf);
}

aetos 2010/05/28(金) 12:54:31
> if( *p > 0x7fff)    *p -= 0x7fff;

この if 文は決して成立しないのでは?

簡単な難読化であれば、各バイトごとに特定の値と XOR するのがよくある手法です。
難読化するときも元に戻す時も同じロジックでいけます。

ところで、根本的な問題ですが、

> 理由は、ユーザ記述のコメントやユーザ情報を含むためです。

というのは?
それはユーザには見えてもいい、ということになりませんか。
他のユーザに見られたくないのであれば、ユーザごとのフォルダ(マイドキュメントや 
AppData)に保存するだけでよいのでは、と思います。

仲澤@失業者 2010/05/28(金) 13:42:22
元の情報量が減らない演算で、暗号に使いやすい演算には、

 1.Bitの(N)回転
 2.ある値(M)とのXOR( aetosさん既出)

等があります。両方とも複数回適用できます。
デコードは、エンコード方法の間逆を行うだけです。
もちろん、N、Mをファイルの属性とした場合は、
ファイルの「どこか」に埋め込んで保管しなければなりません。

さて、提示のコードではUnicodeか、ASCII(MBCS)かが、わかりません。
一般に暗号化などの演算を行う場合はどちらかに決め打ちして
コードした方が良いと思います(つまりTCHARを使わない)。
MBCSの場合、奇数Byteの文字列もありえますので、
たぶんchar単位でやった方が良いでしょう。

ハルキ 2010/05/28(金) 15:47:19
返信ありがとうございます。
XOR 0xFFFFでビット反転させるようにしました。
ビット演算子使えば簡単なこと忘れていました(^^;


//書き込み
if( !ar.IsLoading() ){    
    TCHAR* p = strBuf.GetBuffer();
    while( *p != NULL ) {
        *p ^= 0xffff;
        p++;
    }
    ar << strBuf;
}
//読み込み
else {
    ar >> strBuf;
    TCHAR* p = strBuf.GetBuffer();
    while( *p != NULL ) {
        *p ^= 0xffff;
        p++;
    }
}

>>aetosさん
社内で使用する単純なTOOLのため、exeファイルと同じ階層にLOGファイルとして出力す
る程度です。

bun 2010/05/31(月) 11:35:40
ちょっと気になるのが、
元の文字列に対して、直接 *p ^= 0xffff; してるところ。

演算結果が NULL文字になったりしないか心配です。
NULL文字になれば、ar << strBuf; でそこが文字列終端とみなされます。

なお、シフトJISでは、漢字の1バイト目に0xFFを認めているようです。
(仕様的にであって、実際には現状使われていない模様)

仲澤@失業者 2010/05/31(月) 12:00:07
bunさんの指摘の通り、テキストファイルの場合は
コントロール文字(特に0x00とEOF)にならないようにしなければならないので、
簡単にやるにはファイルをバイナリで作らなければなりませんね。

古いスレッドには追加発言できません。