質問

いく必要がある機密情報(対称暗号化キーが上がっていきたい個)私C ープに適用することができます単純なアプローチはこれを

std::string myKey = "mysupersupersecretpasswordthatyouwillneverguess";

しかし、走行によってアプリケーションへの、 strings プロセス(その他その抽出物から文字列をバイナリのアプリ)を明らかに上記の文字列になります。

えることができるまで使用し訳などに敏感なデータはもらえますか?

編集:

ですが、ほとんど全ての皆さまにわ "ご実行できるリバース-エンジニアリング" -のコース!このペストレの鉱山で行ってい>トはこちら

そして99%(OKでも私は誇張で少し)、全てのセキュリティに関する質問-このサイト回答の奔流のように"なの作り方には、完全に安全プログラム"のではないも!セキュリティを確保することは、スライドと完璧に使いやすいセキュリティの一端とし、万全のセキュリティなしで、ユーザビリティです。

そのポイントはすりの位置とに摺動規模によって何をしようとしていることは、環境るソフトウェアです。 成できませんアプリのための軍事施工、書いアプリのための自宅のパソコン.いる暗号化データは、信頼できないネットワーク事前に知られる暗号鍵があります。この場合、"セキュリティを通じても視線をさえぎ"だろう良い。確かに、誰かの十分な時間、エネルギーとスキルがリバースエンジニアリングは、バイナリのパスワードのものを思うのか。い:

に時間がかかるか実施のトップワンランク上のセキュアなシステムに比べて価格は高くなりますが損失の販売による割れのバージョン(せていただき、また実際に販売でご利用いただけます。っています。このブルースカイ"できないので、絶対に行うので"傾向プログラミングの中に新しいプログラマは愚と言わざるを得ない。

応じて頂きありがとうございまの時にこれらの疑問に答えて気持ちよく対応してくれました。残念ながらきのみ受け付けに一つの答えを、私は最新の投票すべての答えなのです。

役に立ちましたか?

解決

であれば、基本的に誰でもアクセスプログラムやデバッガ ができ の鍵の場合、お申込みいます。

でも、だいたいかどうかを確認するために鍵を表示しませんが走 strings お二きのためのインスタンスに鍵が内部に置くことはできませんの印刷できます。

ぼかしキーとのXOR

例えば、利用のXOR分割を行キーを二つのバイト配列:

key = key1 XOR key2

作成した場合は、key1同じバイトの長さとして key てご利用いただけます(完全に)ランダムバイト値として計算 key2:

key1[n] = crypto_grade_random_number(0..255)
key2[n] = key[n] XOR key1[n]

できないことをビルド環境、その店舗 key1key2 お願います。

を保護するバイナリー

もう一つのアプローチを使用ツールをバイナリー.例えば、複数のセキュリティツールできるいはバイナリはobfuscated開始仮想マシンです。ことが困難であるという(er)デバッグであるとともに、convential多くの商業グレードの確保に用いまた、そのマルウェア)を保護します。

日本デザインコミッティーツール Themida, なカの保護おbinaries.れがしばしば見られますが、それは有名などのプログラムは、世の中は、保護する逆工学です。では、これらの機能デバッグプログラムなどのOllyDbg、Ida Pro.

もより大きなリストのなかにはやや時代遅れの ツールをバイナリー.
一部は無料です。

パスワードのマッチング

誰かがここで議論をハッシュパスワード+塩です。

が必要な場合は、キーマッチに対してほかのユーザーが投稿したブログパーのパスワードを使うことができなハッシュ機能preferrablyを組み合わせユーザー名、パスワードと塩です。このもとに書面にて通知の塩ができるように、すぐそばで楽しむことができ比べのハッシュ.うめだく必要があるの塩のどこかにします。しかし@エドワードポイントにコメントを、この効果的に保護する辞書攻撃に使用。g、レインボーテーブルです。

最後に、利用できるすべての組合せの技術です。

他のヒント

まず第一に、十分に決意したハッカーを止めることができることは何もないということを認識してください。あらゆるゲームとコンソールの保護は最終的に破られるため、これは一時的な修正にすぎません。

しばらくの間、隠れている可能性を高めることができる4つのことがあります。

1)文字列の要素を何らかの方法で非表示にします-文字列を別の文字列とxoring(^演算子)するなどの明らかなことは、文字列を検索できないようにするのに十分です。

2)文字列を分割します-文字列を分割し、その一部を奇妙なモジュールの奇妙な名前のメソッドにポップします。文字列を含むメソッドを簡単に検索して見つけられないようにしてください。もちろん、いくつかのメソッドはこれらすべてのビットを呼び出す必要がありますが、それでも少し難しくなります。

3)文字列をメモリに構築しないでください。ほとんどのハッカーは、エンコードした後、文字列をメモリに表示できるツールを使用します。可能であれば、これを避けてください。たとえば、サーバーにキーを送信する場合は、文字ごとに送信します。したがって、文字列全体が周囲に存在することはありません。もちろん、RSAエンコーディングのようなものから使用している場合、これはより複雑です。

4)アドホックアルゴリズムを実行します-これに加えて、独自のひねりを1つまたは2つ追加します。作成するものすべてに1を追加するか、暗号化を2回実行するか、砂糖を追加します。これにより、たとえばバニラmd5ハッシュやRSA暗号化などを使用しているときに何を探すべきかを既に知っているハッカーにとっては、少し難しくなります。

何よりも、キーが発見されたとき(そして、アプリケーションが十分に人気を博したときに重要になる)に、それが重要すぎないことを確認してください!

過去に使用した戦略は、一見ランダムな文字の配列を作成することです。最初に挿入してから、代数プロセスを使用して特定の文字を見つけ、0〜Nの各ステップで数値<!> ltが生成されます。難読化された文字列の次の文字を含む配列のサイズ。 (この答えは今では難読化されているようです!)

例:

文字の配列を指定します(数字とダッシュは参照専用です)

0123456789
----------
ALFHNFELKD
LKFKFLEHGT
FLKRKLFRFK
FJFJJFJ!JL

そして最初の6つの結果が3、6、7、10、21、47である方程式

単語<!> quot; HELLO!<!> quot;上記の配列から。

@Checkersに同意します。実行可能ファイルをリバースエンジニアリングできます。

もう少し良い方法は、動的に作成することです。例:

std::string myKey = part1() + part2() + ... + partN();

文字列用の単純な暗号化ツールを作成しました。暗号化された文字列を自動的に生成でき、そのためのいくつかの追加オプション、いくつかの例があります:

グローバル変数としての文字列:

// myKey = "mysupersupersecretpasswordthatyouwillneverguess";
unsigned char myKey[48] = { 0xCF, 0x34, 0xF8, 0x5F, 0x5C, 0x3D, 0x22, 0x13, 0xB4, 0xF3, 0x63, 0x7E, 0x6B, 0x34, 0x01, 0xB7, 0xDB, 0x89, 0x9A, 0xB5, 0x1B, 0x22, 0xD4, 0x29, 0xE6, 0x7C, 0x43, 0x0B, 0x27, 0x00, 0x91, 0x5F, 0x14, 0x39, 0xED, 0x74, 0x7D, 0x4B, 0x22, 0x04, 0x48, 0x49, 0xF1, 0x88, 0xBE, 0x29, 0x1F, 0x27 };

myKey[30] -= 0x18;
myKey[39] -= 0x8E;
myKey[3] += 0x16;
myKey[1] += 0x45;
myKey[0] ^= 0xA2;
myKey[24] += 0x8C;
myKey[44] ^= 0xDB;
myKey[15] ^= 0xC5;
myKey[7] += 0x60;
myKey[27] ^= 0x63;
myKey[37] += 0x23;
myKey[2] ^= 0x8B;
myKey[25] ^= 0x18;
myKey[12] ^= 0x18;
myKey[14] ^= 0x62;
myKey[11] ^= 0x0C;
myKey[13] += 0x31;
myKey[6] -= 0xB0;
myKey[22] ^= 0xA3;
myKey[43] += 0xED;
myKey[29] -= 0x8C;
myKey[38] ^= 0x47;
myKey[19] -= 0x54;
myKey[33] -= 0xC2;
myKey[40] += 0x1D;
myKey[20] -= 0xA8;
myKey[34] ^= 0x84;
myKey[8] += 0xC1;
myKey[28] -= 0xC6;
myKey[18] -= 0x2A;
myKey[17] -= 0x15;
myKey[4] ^= 0x2C;
myKey[9] -= 0x83;
myKey[26] += 0x31;
myKey[10] ^= 0x06;
myKey[16] += 0x8A;
myKey[42] += 0x76;
myKey[5] ^= 0x58;
myKey[23] ^= 0x46;
myKey[32] += 0x61;
myKey[41] ^= 0x3B;
myKey[31] ^= 0x30;
myKey[46] ^= 0x6C;
myKey[35] -= 0x08;
myKey[36] ^= 0x11;
myKey[45] -= 0xB6;
myKey[21] += 0x51;
myKey[47] += 0xD9;

復号化ループを含むUnicode文字列として:

// myKey = "mysupersupersecretpasswordthatyouwillneverguess";
wchar_t myKey[48];

myKey[21] = 0x00A6;
myKey[10] = 0x00B0;
myKey[29] = 0x00A1;
myKey[22] = 0x00A2;
myKey[19] = 0x00B4;
myKey[33] = 0x00A2;
myKey[0] = 0x00B8;
myKey[32] = 0x00A0;
myKey[16] = 0x00B0;
myKey[40] = 0x00B0;
myKey[4] = 0x00A5;
myKey[26] = 0x00A1;
myKey[18] = 0x00A5;
myKey[17] = 0x00A1;
myKey[8] = 0x00A0;
myKey[36] = 0x00B9;
myKey[34] = 0x00BC;
myKey[44] = 0x00B0;
myKey[30] = 0x00AC;
myKey[23] = 0x00BA;
myKey[35] = 0x00B9;
myKey[25] = 0x00B1;
myKey[6] = 0x00A7;
myKey[27] = 0x00BD;
myKey[45] = 0x00A6;
myKey[3] = 0x00A0;
myKey[28] = 0x00B4;
myKey[14] = 0x00B6;
myKey[7] = 0x00A6;
myKey[11] = 0x00A7;
myKey[13] = 0x00B0;
myKey[39] = 0x00A3;
myKey[9] = 0x00A5;
myKey[2] = 0x00A6;
myKey[24] = 0x00A7;
myKey[46] = 0x00A6;
myKey[43] = 0x00A0;
myKey[37] = 0x00BB;
myKey[41] = 0x00A7;
myKey[15] = 0x00A7;
myKey[31] = 0x00BA;
myKey[1] = 0x00AC;
myKey[47] = 0x00D5;
myKey[20] = 0x00A6;
myKey[5] = 0x00B0;
myKey[38] = 0x00B0;
myKey[42] = 0x00B2;
myKey[12] = 0x00A6;

for (unsigned int fngdouk = 0; fngdouk < 48; fngdouk++) myKey[fngdouk] ^= 0x00D5;

グローバル変数としての文字列:

// myKey = "mysupersupersecretpasswordthatyouwillneverguess";
unsigned char myKey[48] = { 0xAF, 0xBB, 0xB5, 0xB7, 0xB2, 0xA7, 0xB4, 0xB5, 0xB7, 0xB2, 0xA7, 0xB4, 0xB5, 0xA7, 0xA5, 0xB4, 0xA7, 0xB6, 0xB2, 0xA3, 0xB5, 0xB5, 0xB9, 0xB1, 0xB4, 0xA6, 0xB6, 0xAA, 0xA3, 0xB6, 0xBB, 0xB1, 0xB7, 0xB9, 0xAB, 0xAE, 0xAE, 0xB0, 0xA7, 0xB8, 0xA7, 0xB4, 0xA9, 0xB7, 0xA7, 0xB5, 0xB5, 0x42 };

for (unsigned int dzxykdo = 0; dzxykdo < 48; dzxykdo++) myKey[dzxykdo] -= 0x42;

もちろん、ユーザーに出荷されるソフトウェアに個人データを保存することは常にリスクです。十分な教育を受けた(そして専任の)エンジニアなら誰でもデータをリバースエンジニアリングできます。

そうは言っても、個人データを明らかにするために人々が乗り越えなければならない障壁を高めることで、物事を十分に安全にすることができます。それは通常、良い妥協です。

あなたの場合、印刷できないデータで文字列を乱雑にし、次のような単純なヘルパー関数を使用して実行時にそれをデコードできます:

void unscramble( char *s )
{
    for ( char *str = s + 1; *str != 0; str += 2 ) {
        *s++ = *str;
    }
    *s = '\0';
}

void f()
{
    char privateStr[] = "\001H\002e\003l\004l\005o";
    unscramble( privateStr ); // privateStr is 'Hello' now.

    string s = privateStr;
    // ...
}

joshperryが指摘するように、保護しようとしているものに多少依存しています。 経験から、ソフトウェアを保護するためのライセンススキームの一部である場合、気にしないでください。最終的にリバースエンジニアリングを行います。 ROT-13のような単純な暗号を使用して、単純な攻撃(文字列が文字列で実行されている)から保護します。 ユーザーの機密データを保護する場合、ローカルに保存された秘密キーでそのデータを保護することは賢明なことかどうか疑問に思うでしょう。繰り返しますが、保護しようとしているものに帰着します。

編集:クリスが指摘する手法の組み合わせは、rot13よりもはるかに優れています。

前述のとおり、文字列を完全に保護する方法はありません。しかし、合理的な安全性でそれを保護する方法があります。

これをしなければならなかったとき、私はコードに無害な外観の文字列(たとえば、著作権表示、または偽のユーザープロンプト、無関係なコードを修正する誰かによって変更されないもの)を入れました自分自身をキーとして使用し、それをハッシュ(ソルトを追加)し、その結果をキーとして使用して、実際に暗号化するものを暗号化しました。

もちろんこれはハッキングされる可能性がありますが、それを行うには断固としたハッカーが必要です。

秘密キーを実行可能ファイルに保存する代わりに、ユーザーにリクエストして、外部パスワードマネージャー、Mac OS Xキーチェーンアクセスに似たもの。

WindowsユーザーDPAPIを使用している場合、 http://msdn.microsoft .com / en-us / library / ms995355.aspx

以前の投稿で述べたように、Macを使用している場合はキーチェーンを使用してください。

基本的に、バイナリ内に秘密鍵を保存する方法についてのこれらのかわいいアイデアはすべて、セキュリティの観点からは不十分であり、実行すべきではありません。秘密鍵を取得する人は誰でも大したことです。プログラム内に保管しないでください。アプリのインポート方法に応じて、秘密キーをスマートカードに保存したり、コードが通信するリモートコンピューターに保存したり、ほとんどの人が行うことを実行してローカルコンピューターの非常に安全な場所に保存することができます(<! > quot; key store <!> quot;これは、奇妙で安全なレジストリのようなものです)、許可とOSのすべての強度によって保護されています。

これは解決された問題であり、答えはプログラム内にキーを保持することではありません:)

こちらをお試しください。ソースコードは、指定されたVisual Studio c ++プロジェクトのすべての文字列をオンザフライで暗号化および復号化する方法を説明しています。

最近試した方法の1つは次のとおりです。

  1. プライベートデータのハッシュ(SHA256)を取得し、コードにpart1
  2. として入力します
  3. プライベートデータとそのハッシュのXORを取得し、part2
  4. としてコードに入力します
  5. データの入力:char str []として保存せず、実行時に割り当て命令を使用して入力します(以下のマクロを参照)
  6. 今、<=>と<=>
  7. のXORを取ることにより、実行時にプライベートデータを生成します
  8. 追加手順:生成されたデータのハッシュを計算し、<=>と比較します。プライベートデータの整合性を検証します。

データを入力するMACRO:

プライベートデータが4バイトであるとします。そのためのマクロを定義し、ランダムな順序で割り当て命令とともにデータを保存します。

#define POPULATE_DATA(str, i0, i1, i2, i3)\
{\
    char *p = str;\
    p[3] = i3;\
    p[2] = i2;\
    p[0] = i0;\
    p[1] = i1;\
}

次のように、<=>および<=>を保存する必要があるコードでこのマクロを使用します。

char part1[4] = {0};
char part2[4] = {0};
POPULATE_DATA(part1, 1, 2, 3, 4); 
POPULATE_DATA(part2, 5, 6, 7, 8);

コンテキストに依存しますが、キーのハッシュ salt (定数文字列、わかりにくい)を保存するだけで済みます。

その後、ユーザーがキーを入力した場合、 salt を追加し、ハッシュを計算して比較します。

salt はおそらくこの場合は不要です。ハッシュを分離できる場合、ブルートフォース辞書攻撃を阻止します(Google検索も機能することがわかっています)。

ハッカーはjmp命令を挿入するだけでロット全体をバイパスできますが、単純なテキスト検索よりもかなり複雑です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top