2012-05-04 153 views
22

我從來沒有想過,只有我用方法getPassword,返回一個字符數組,我看到getText方法是已棄用。但現在我想,爲什麼這種方法是已棄用爲什麼JPasswordField中的getText()已被棄用?

Java文檔解釋:

棄用從Java 2平臺v1.2開始,由getPassword取代。

獲取組件表示的部分文本。如果長度爲0,則返回 空字符串。

出於安全原因,此方法爲 已棄用。改爲使用getPassword方法。

但那些是什麼安全原因?有關於此的任何想法?

預先感謝您。

+2

的http://計算器。com/questions/983964/why-does-jpasswordfield-getpassword-create-a-string-with-the-password-in-it – Garbage

回答

36

當調用getText時,你會得到一個String(不可變對象),它可能不會被改變(反射除外),所以密碼一直保留在內存中,直到垃圾收集。

當調用getPassword時,會得到一個可能被修改的字符數組,因此密碼將不會保留在內存中。

8

原因是,如果您要求將密碼作爲字符串而不是字符數組,那麼包含密碼的字符串現在將在Java運行時的內存中浮動一段非特定的時間。它可能會被一個流氓Java組件或外部程序從那裏讀取。

通過使用char數組,您可以驗證密碼,然後立即對其進行加密。

5

此行爲背後的原因是Java字符串池(有關更多信息,請參閱,例如this SO question)。只要您將該密碼字段的內容轉換爲String(如果使用getText方法會發生什麼情況)String將被放置在池中,並且可以被其他人讀取。

如果你想看看getPassword方法的實現(如可以在SO question @Garbage張貼在你的問題中留言中可以看出),你可以看到這個精心以避免創建String

注意,這也意味着你不應該做這樣的事情

if (Arrays.equals("mySuperSecretPassword".toCharArray(), passwordField.getPassword())) 

,或者你還結了把密碼池中,然後你可以容易地使用了getText方法。

+0

「Java字符串池」用於編譯時的內部常量..我質疑是否一個標準的Swing文本輸入*真正*實際輸入文本值。我的理解是,返回一個char []數組而不是不可變的String允許密碼立即清零,以儘量減少工作內存中的暴露/可見性(安全最佳實踐)。該字符串永遠不會被期望以任何方式「實習」。 –

5

試試這個:

String myPass=String.valueOf(passwordField.getPassword()); 
+1

OP不要求*如何獲取密碼作爲'String' *;他問*爲什麼密碼以「CharrArray」而不是「String」的形式返回。 – Barranka

相關問題