Ви можете почути таке питання на інтерв'ю на позицію Java Junior. Але моєму приятелю його поставабо на співбесіді на посаду Technical Lead.
І
String
, і масив символів можна використовуватиме зберігання текстових даних. Але усвідомлений вибір одного чи іншого для конкретного завдання складний, якщо ви ще не стикалися з подібною ситуацією. Однак, як зауважив мій друг, будь-яке питання, пов'язане з
String
, зазвичай пов'язане з таким особливим властивістю рядків, як незмінність (
Immutable
), і він скористався цим на співбесіді. Отже, давайте розберемо кілька причин, чому для зберігання пароля потрібно використовувати
char []
, а не
String
.
Причина 1. Рядки – незмінні
Оскільки рядки в Java є незмінними, ваш пароль у вигляді звичайного тексту буде доступний у пам'яті, поки збирач сміття не очистить її. І оскільки
String
використовуються
String pool
для повторного використання, існує досить висока ймовірність того, що пароль залишиться в пам'яті надовго, що зовсім не безпечно.
Java String pool - це пул або набір об'єктів (рядків), який розташований у спеціальному місці - купі (Heap). String в Java - один із найпоширеніших типів даних. Не примітивний тип, а об'єкт, оскільки дуже ресурсозатратний. Так, для зберігання рядка із чотирьох символів необхідно виділити 56 байт пам'яті. Ось чому рядки, як і інші об'єкти, зберігаються в купі. |
Будь-який, хто має доступ до дампи пам'яті, може знайти пароль у текстовому вигляді, і це є серйозною причиною, щоб використовувати зашифрований пароль, а не простий текст. Оскільки рядки є незмінними, їх не можна змінити. Будь-яка зміна призведе до створення нового рядка. А ось у випадку з
char []
, ви можете замінити будь-який його елемент банкрутом або порожнім символом. Таким чином зберігання пароля в масиві символів явно знижує ризик перехоплення пароля.
Причина 2. Рекомендації авторів
Java сама по собі (ну, через своїх творців, зрозуміло) рекомендує використовувати метод
getPassword ()
із класу
JPasswordField
, який повертає
char []
. Можна також спробувати застарілий (deprecated) метод
getText ()
. Чому б не наслідувати рекомендації авторів мови?
Причина 3. Друк
З типом
String
завжди існує небезпека того, що текст, що зберігається в рядку, буде надрукований у файлі логів або в консолі. У той же час у випадку використання
Array
, ви не друкуватимете вміст масиву, а тільки його розташування в пам'яті. Звичайно, це не те щоб серйозна причина, але все ж таки в цьому теж є сенс.
String strPassword = "Unknown";
char [] charPassword = new char [] {'U', 'n', 'k', 'w', 'o', 'n'};
System.out.println ("String password:" + strPassword);
System.out.println ("char password:" + charPassword);
String password: Unknown
Character password: [C@110b053
Зрозуміло, використання
char []
для зберігання паролів Java само по собі не є панацеєю. Вам потрібно потурбуватися про безпеку, наприклад, працювати з хешами та шифрувати паролі, а не зберігати їх у текстовому вигляді. І, звичайно, видаляти його з пам'яті одразу після процедури аутентифікації.
За матеріалами Javarevisited
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ