[解決済み] C++で機密性の高い文字列を隠蔽するためのテクニック
質問
C++アプリケーションに機密情報(非公開にしたい対称暗号鍵)を保存する必要があります。簡単な方法としては、次のようになります。
std::string myKey = "mysupersupersecretpasswordthatyouwillneverguess";
しかし、アプリケーションを実行する際に
strings
プロセス (またはバイナリ アプリケーションから文字列を抽出する他の任意のもの) を通してアプリケーションを実行すると、上記の文字列が表示されます。
このような機密データを見えなくするために、どのような技術を使うべきでしょうか?
編集してください。
OK、では、かなりの人が あなたの実行ファイルをリバース エンジニアリングすることができます。 - と言っています。これは私の嫌いなところなので、ここで少しわめき散らしてみようと思います。
なぜこのサイトのセキュリティ関連の質問の 99% (OK、少し誇張しているかもしれませんが) は、「完璧に安全なプログラムを作成する方法はありません」という激流で回答されているのでしょうか? セキュリティは、一方では完璧な使いやすさとセキュリティなし、もう一方では完璧なセキュリティと使いやすさの間のスライディング スケールなのです。
ポイントは、何をしようとしているか、そしてソフトウェアが実行される環境に応じて、そのスライディング スケール上の位置を選択することです。
私は軍事施設用のアプリケーションを作成しているのではなく、家庭用 PC 用のアプリケーションを作成しているのです。 . 信頼されていないネットワーク上のデータを、あらかじめ知られている暗号化キーで暗号化する必要があります。このような場合、曖昧さによるセキュリティで十分でしょう。確かに、十分な時間とエネルギーと技術を持った人なら、バイナリをリバースエンジニアリングしてパスワードを見つけることは可能でしょうが、どうでしょう?私は気にしません。
一流の安全なシステムを実装するのにかかる時間は、クラックされたバージョンによる売上損失よりも高価です (実際にこれを販売しているわけではありませんが、私の言いたいことはわかりますよね)。新しいプログラマーの間でのプログラミングにおけるこの青天井の "可能な限り最高の方法でやりましょう"というトレンドは、控えめに言っても愚かなことです。
この質問に時間を割いて回答していただき、ありがとうございます - これらは非常に役に立ちました。残念ながら、私は 1 つの回答しか受け入れることができませんが、有用な回答はすべてアップロードしておきました。
どのように解決するのですか?
基本的には、プログラムとデバッガにアクセスできる人なら誰でも ができます。 と 意志 はアプリケーションでキーを見つけようと思えば見つけられます。
を実行したときにキーが表示されないようにしたいだけならともかく、そのような場合は
strings
を実行したときにキーが表示されないようにするだけなら、例えばキーが印刷可能な範囲にないことを確認することができます。
XORでキーを隠蔽する
例えば、XORを使ってキーを2つのバイト配列に分割することができます。
key = key1 XOR key2
と同じバイト長でkey1を作成すると
key
と同じバイト長で作成すると、(完全に)ランダムなバイト値を使用することができ、その上で
key2
:
key1[n] = crypto_grade_random_number(0..255)
key2[n] = key[n] XOR key1[n]
これをビルド環境で行うことで、ビルド時にのみ格納される
key1
と
key2
を追加してください。
バイナリの保護
もう一つの方法は、バイナリを保護するためのツールを使用することです。 たとえば、バイナリが難読化され、その上で実行される仮想マシンを起動することを確認できるセキュリティ ツールがいくつか存在します。 これは、デバッグを困難にし、多くの商用グレードの安全なアプリケーション (残念ながら、マルウェア) を保護する一般的な方法です。
最も優れたツールの 1 つが テミーダ で、これはバイナリを保護する素晴らしい仕事をします。 これは、リバースエンジニアリングから保護するために、Spotify のような有名なプログラムでよく使用されています。 また、OllyDbg や Ida Pro などのプログラムでのデバッグを防止する機能も備えています。
また、より大きなリストもあります。
バイナリを保護するためのツール
.
中には無料のものもあります。
パスワード照合
パスワードとソルトのハッシュ化について議論した人がいます。
もし、ユーザーが提出したある種のパスワードと照合するためにキーを保存する必要があるなら、ユーザー名、パスワード、ソルトを組み合わせた一方向ハッシュ関数を使用することが望ましいです。 しかし、この問題は、アプリケーションがソルトを知らなければ、一方向ハッシュを実行し、結果のハッシュを比較することができないことです。 そのため、アプリケーションのどこかにソルトを保存しておく必要があります。しかし、@Edward が以下のコメントで指摘しているように、これは例えばレインボーテーブルを使った辞書攻撃から効果的に保護することができます。
最後に、上記のすべてのテクニックを組み合わせて使うことができます。
関連
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] 後で平文を取り出すためのユーザーパスワードの保管について、倫理的にどのように取り組むべきでしょうか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み】高放射能環境下で使用するアプリケーションのコンパイルについて
-
[解決済み】PHPパスワードのハッシュとソルトの安全性について
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] 配列のベクトルを扱う正しい方法