2017-02-19 19 views
0

JavaはURLエンコード文字列にURLEncoderクラスを提供します。しかし、it is considered insecure to store passwords as Strings。このコードはHttpsURLConnection出力ストリームwrで十分安全なPOST経由でパスワードを送信しますか?パスワードを安全にURLエンコード

try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) { 
    // Write some post params 
    for (char c : pass) { 
     wr.writeBytes(URLEncoder.encode(String.valueOf(c), "UTF-8")); 
    } 
    // Write some more 
} 

一方では、Stringsを使用しています。一方、これらの文字列は1文字の長さであり、エンコーディング後は概念的に同じです。また、マルチバイト文字では失敗する可能性があります。攻撃者はこれらの1-char文字列をメモリに配置して元のパスワードを再構築できますか?これを行うより良い方法はありますか?

+0

私はあなたの言いたいことはありません。メモリにパスワードを表現する方法については言及していません。 *あなた*は*送信*パスワードについて話しています。それは同じではない*同じですか? – GhostCat

+0

@GhostCat私は安全でない形式でパスワードをメモリに保存せずにパスワードを送信する方法について話しています。 –

+0

@GhostCat具体的には、自分のパスワードの個々の文字をストリングとして保存するのが安全かどうか疑問に思っています。攻撃者はこれらの文字列を見つけてパスワードを再構築できますか? –

答えて

2

文字列をパスワードに使用すると、Stringの内容を手動で(反射を除いて)ゼロにすることができず、内容が不明な時間メモリに残りますので、確実に破棄することはできません。したがって、char[]は、パスワード入力に使用することが推奨され、続いて前記char[]の手動ゼロ設定が行われます。

ただし、メモリにアクセスする必要があるため、攻撃は決して容易ではありません。タイミングは幸いです。 GCが作業を行い、メモリが再利用されるため、パスワードが非常に長い時間メモリに残ることはほとんどありません。ほとんどの場合、この攻撃ベクトルは他のより単純な攻撃に比べて実行不可能です。

0

OutputStreamには、方法がありません。writeBytes;それはすべての文字のパスワードをと書くことができるwrite(byte [])メソッドを提供します。呼び出しです。

それを超えて:HTTPSを使用することの全体の考え方は、接続自体がであり、安全に暗号化されているということです。;そのようなコンテンツをシングルバイトまたはマルチバイトのバーストで送信するかどうかは重要ではありません。

次に、これらすべてのクラスは、互いに重なっているという抽象度であることに注意してください。 HTTPSはTCPを使用します。 TCPパケットは特定のサイズを持ちます。その意味では、とにかく1つのバイトがネットワークを経由することはありません。

質問の2番目の部分について:char値の配列を反復処理しています。だからそれは本当に依存するどのようにその文字配列が作成された;通常は心配する必要はありません(そのトピックのhereを参照)。

+0

リンク先の記事を読んでください。これは、パスワードをストリングとして保存することであり、セキュリティーに関するものではありません。実際には 'DataOutputStream'を使用しています。それを私の質問に追加します。 –

+0

char配列は、たとえばから作成されました。 'JPasswordField.getPassword()' –

+0

@BrianMcCutchonつまり、このchar配列がパスワードを表すと信じることができます。あなたが信頼できるテスト用のライブラリコンポーネントを利用しているからです。つまり、配列内の個々の文字がutf8で表現できないことを心配する必要はありません。 – GhostCat

関連する問題