2013-05-22 10 views
21

Javaでは、パスワードなどの秘密情報を保存する古い方法は、完了した時点でデータを上書きできるので、char[]を使用することでした。しかし、これはガベージコレクタがヒープを再構成するときに物事をコピーするので、これは安全でないことが示されています。特定のアーキテクチャでは、あるページが解放され、他のプログラムが同じページを割り当てたときにシークレットが残る可能性があります。秘密をJavaのスタックに保存することはできますか?

これはひどく醜いですが、秘密がスレッドのrunメソッドのスタックに格納されていた場合はどうなりますか?スレッドを正常終了させるためには、データをゼロにすることができるように注意する必要がありますが、この問題は古い方法でも発生しています。

私がすぐに見ている大きな問題の1つは、データをコンテナに出し入れする安全な方法を考えることができないということです。非常に小さな内部バッファを持つストリームを使用することによって漏洩した秘密の可能性を最小限に抑えることができますが、最終的にはchar[]という同じ問題が発生します。 [編集:単一のprivate static byteメンバーとフラグが動作しますか?それはClassLoaderごとに1つの秘密に制限されますが。これにより、より醜さが増しますが、十分に書かれたインターフェイスの背後に隠れるほど簡単になるかもしれません。]実際には、たくさんの質問があります。

スタックは、これらの種類の攻撃からヒープより安全ですか?この問題に有用な方法で、2つの異なるスタックフレーム間でスタック間コピーを実行する純粋なJavaメカニズムがありますか?もしそうでなければ、JVMはこのタイプの操作をバイトコードでサポートしますか?

[編集:人々があまりにも心配する前に、これは他の何よりも考えられた実験です。私は、「プロダクションでテストする」ことも、現在のプロジェクトで使用することも絶対に意図していません。私が話していることは、実際には醜い、おそらく恐ろしくかさばり、JVMの構造全体に対して働いていることに気づいています。私はそれが可能かどうか、それが実際に自分の目標を達成するかどうか、どんな種類のヒーローが起こるかに興味があります。]

+5

攻撃者がこのようなデータにアクセスすることを正当に懸念している場合は、このレベルで心配するほど洗練された攻撃者は、それらを投げる。 –

+0

原則として私は同意しますが、それは脅威を閉鎖するための非常に貧しい議論です。いずれにしても、クライアントから提供されたセキュリティ要件のリストを確認する際に、この手順を開始しました。 1つは、常に秘密をゼロにすることです。これを怠ると、審査の際にクライアントが摘発します。クライアントは、 'char []'が動作しないことを理解するのに十分にスマートですが、Javaを使うことも義務づけています。幸いにも彼らは合理的な人々です、彼らは紛争を認識し、あまりにも大きな懸念事項ではありません。しかし、それは私に考えさせてくれました... –

+0

脅威を閉鎖することに対して非常に貧しい議論* - 申し訳ありませんが、編集期限が切れました。 –

答えて

12

私は直接ByteBufferを使用します。このメモリが使用するメモリはコピーされず、ByteBufferの存続期間中は1つの場所にのみ存在します。 BTWは、単に位置をリセットするので、clear()を使用しないでください。あなたは、任意のより安全なこの種の攻撃からヒープよりスタックです

bb.clear(); 
while(bb.remaining() >= 8) bb.putLong(0); 
while(bb.remaining() > 0) bb.put((byte) 0); 

でそれを上書きすることができますか?

私はそうは思わないでしょう。

2つの異なるスタックフレーム間でこの問題に役立つ方法でスタックツースタックコピーを実行する純粋なJavaメカニズムがありますか?

秘密を1つまたは2つのlongとして保存することができます。

もしそうでなければ、JVMはこのタイプの操作をバイトコードでサポートしますか?

バイトコードは、Javaをサポートするように設計されており、Javaでできることはほとんどありません。

私はそれが実際に私の目標を達成するかどうか、そしてそれは私が提案してきたように、直接のByteBufferを使用し

を実現するためにかかる英雄の種類を、それが可能だかどうかでちょうど興味があります。 ;)

+0

"このメモリはコピーされません..." - 内部で 'byte []'を使用しませんか?これはヒープ上に格納されており、他の配列(前述の 'char []'のような)と同様に、GCによる再編成をヒープすることができます。 –

+2

ヒープByteBufferはバイト[]を使用し、ダイレクトByteBufferはネイティブメモリを使用します。ネイティブメモリにはgcが触れていません。 –

+0

これはjvmメモリに保存するよりも安全ですか? –

関連する問題