Почему char [] предпочтительнее, чем String для паролей?

3016

В Swing поле пароля имеет метод getPassword() (возвращает char[]) вместо обычного метода getText() (возвращает String). Точно так же я столкнулся с предложением не использовать String для обработки паролей.

Почему String создает угрозу безопасности при использовании паролей? Это неудобно использовать char[].

  • 21
    Можете ли вы привести источник предложения? Я не могу придумать причину, по которой char[] был бы более безопасным, за исключением, может быть, самых любительских угроз.
  • 143
    @Viruzzo взгляните на Javadocs. Метод getText() в JPasswordField не рекомендуется в пользу getPassword() «по соображениям безопасности».
Показать ещё 11 комментариев
Теги:
string
security
passwords
char

18 ответов

3661
Лучший ответ

Строки неизменяемы. Это означает, что после создания String, если другой процесс может сбрасывать память, нет способа (кроме reflection), вы можете избавиться от данных, прежде чем сбор мусора начнется.

С помощью массива вы можете явно стереть данные после того, как вы закончите с ним. Вы можете переписать массив всем, что угодно, и пароль не будет присутствовать нигде в системе, даже до сбора мусора.

Итак, это проблема безопасности, но даже использование char[] только уменьшает окно возможностей для злоумышленника и только для этого конкретного типа атаки.

Как отмечалось в комментариях, возможно, что массивы, перемещаемые сборщиком мусора, оставят бездействующие копии данных в памяти. Я считаю, что это специфично для реализации - сборщик мусора может очистить всю память, как есть, чтобы избежать такого рода вещей. Даже если это так, есть еще время, в течение которого char[] содержит фактические символы в качестве окна атаки.

  • 113
    Насколько я понимаю, что при объеме реорганизации памяти, который может быть выполнен во время выполнения, копии даже char[] могут остаться в памяти и никогда не очищаться до тех пор, пока эта память не будет повторно использована. Хотя я не знаю источника, который это подтверждает. В любом случае, я сомневаюсь, что строка будет очищена во время GC, а скорее во время перераспределения объекта в этой памяти.
  • 31
    @Mark Peters: Если GC включится, перед тем как очистить массив символов, у вас будет еще одна копия. Но эта копия, по крайней мере, находится в интенсивно используемой области памяти, поэтому высока вероятность, что она быстро перезаписывается.
Показать ещё 30 комментариев
1114

В то время как другие предложения здесь выглядят действительно, есть еще одна веская причина. С обычным String у вас гораздо больше шансов случайно распечатать пароль для журналов, мониторов или другого небезопасного места. char[] менее уязвим.

Рассмотрим это:

public static void main(String[] args) {
    Object pw = "Password";
    System.out.println("String: " + pw);

    pw = "Password".toCharArray();
    System.out.println("Array: " + pw);
}

Печать

String: Password
Array: [C@5829428e
  • 26
    @ Voo, но я сомневаюсь, что вы войдете через прямую запись в поток и объединение. каркас журналирования преобразует char [] в хороший вывод
  • 33
    @ Thr4wn Реализацией по умолчанию для toString является classname@hashcode . [C представляет char[] , остальное - шестнадцатеричный хеш-код.
Показать ещё 9 комментариев
603

Чтобы процитировать официальный документ, Руководство по архитектуре криптографии Java говорит об использовании паролей char[] vs. String (о шифровании на основе пароля, но это в общем, о паролях, конечно):

Казалось бы логичным собирать и хранить пароль в объекте типа java.lang.String. Однако здесь предостережение: Object of тип String являются неизменяемыми, т.е. нет методов, которые определяют, что позволяют изменять (перезаписывать) или обнулять содержимое Stringпосле использования. Эта функция делает объекты String непригодными для хранения секретной информации, такой как пароль пользователя. Вы должен всегда собирать и хранить конфиденциальную информацию безопасности в char.

В Руководстве 2-2 Руководства по безопасному кодированию для языка программирования Java версии 4.0 также говорится о чем-то подобном (хотя он первоначально находится в контексте ведения журнала):

Руководящий принцип 2-2: не регистрировать высокочувствительную информацию

Некоторая информация, такая как номера социального страхования (SSN) и пароли, очень чувствительны. Эта информация не должна сохраняться дольше, чем необходимо, и там, где это возможно, даже администраторы. Например, он не должен быть отправлен в файлы журналов и его присутствие не должно обнаруживаться при поиске. Некоторые переходные процессы данные могут храниться в изменяемых структурах данных, таких как массивы char, и очищается сразу после использования. Очистка структур данных сократилась эффективности по типичным системам времени исполнения Java, поскольку объекты перемещаются в памяти прозрачно программисту.

Это руководство также имеет последствия для внедрения и использования библиотеки нижнего уровня, не имеющие семантического знания данных они имеют дело с. В качестве примера, синтаксический анализ на нижнем уровне библиотека может регистрировать текст, над которым он работает. Приложение может анализировать SSN с библиотекой. Это создает ситуацию, когда SSN доступный для администраторов, имеющих доступ к файлам журнала.

  • 2
    это именно ошибочная / фиктивная ссылка, о которой я говорю ниже в ответе Джона, это хорошо известный источник с большим количеством критики.
  • 33
    @bestass не могли бы вы также привести ссылку?
Показать ещё 3 комментария
304

Массивы символов (char[]) можно очистить после использования, установив каждый символ в ноль, а строки - нет. Если кто-то может каким-то образом увидеть изображение в памяти, они могут видеть пароль в виде обычного текста, если используются строки, но если используется char[], после очистки данных с 0, пароль защищен.

  • 8
    Не защищен по умолчанию. Если мы говорим о веб-приложении, большинство веб-контейнеров передают пароль в объект HttpServletRequest в виде открытого текста. Если версия JVM - 1.6 или ниже, она будет в постоянном пространстве. Если он в 1.7, он все еще будет читаемым, пока не будет собран. (Когда бы это ни было.)
  • 1
    @avgvstvs: строки не перемещаются автоматически в пространство permgen, это относится только к интернированным строкам. Кроме того, пространство permgen также подлежит сборке мусора, только по более низкой ставке. Реальная проблема с пространством permgen - это его фиксированный размер, и именно поэтому никто не должен бездумно вызывать intern() для произвольных строк. Но вы правы в том, что экземпляры String существуют в первую очередь (до тех пор, пока они не будут собраны), и превращение их в массивы char[] впоследствии не изменит их.
Показать ещё 7 комментариев
203

Некоторые люди считают, что вам нужно перезаписать память, используемую для хранения пароля, как только она вам больше не понадобится. Это уменьшает время, которое атакующий должен прочитать пароль из вашей системы и полностью игнорирует тот факт, что злоумышленнику уже достаточно нужен доступ, чтобы захватить JVM-память для этого. Злоумышленник с таким доступом может поймать ваши ключевые события, делая это совершенно бесполезным (AFAIK, поэтому, пожалуйста, поправьте меня, если я ошибаюсь).

Обновление

Благодаря комментариям я должен обновить свой ответ. По-видимому, есть два случая, когда это может добавить (очень) незначительное улучшение безопасности, поскольку это сокращает время, когда пароль может приземлиться на жесткий диск. Тем не менее, я думаю, что это слишком много для большинства случаев.

  • Ваша целевая система может быть плохо сконфигурирована, или вы должны предположить, что она есть, и вы должны быть параноидальными в отношении дампов ядра (может быть действительным, если системы не управляются администратором).
  • Ваше программное обеспечение должно быть чрезмерно параноидальным, чтобы предотвратить утечку данных, когда злоумышленник получает доступ к аппаратным средствам - используя такие функции, как TrueCrypt (прекращено), VeraCrypt, или CipherShed.

Если возможно, отключение дампов ядра и файла подкачки позаботится обо всех проблемах. Тем не менее, они потребуют прав администратора и могут уменьшить функциональность (меньше памяти для использования) и вытащить ОЗУ из запущенной системы все равно будут иметь серьезную озабоченность.

  • 29
    Я бы заменил «совершенно бесполезный» на «просто незначительное улучшение безопасности». Например, вы можете получить доступ к дампу памяти, если у вас есть доступ на чтение к каталогу tmp, плохо настроенная машина и сбой в вашем приложении. В этом случае вы не сможете установить кейлоггер, но вы можете проанализировать дамп ядра.
  • 38
    Стирание незашифрованных данных из памяти, как только вы закончите, считается лучшей практикой, а не потому, что она надежна (это не так); но потому что это снижает уровень вашей угрозы. Атаки в реальном времени не предотвращаются этим; но поскольку он служит инструментом уменьшения ущерба, значительно сокращает объем данных, которые подвергаются обратной атаке на снимок памяти (например, копия памяти ваших приложений, которая была записана в файл подкачки или была прочитана из памяти, извлечена из памяти) с работающего сервера и перешел на другой, прежде чем его состояние не удалось).
Показать ещё 18 комментариев
119
  • Строки являются неизменяемыми в Java, если вы храните пароль в виде обычного текста, он будет доступен в памяти до тех пор, пока сборщик мусора не очистит его, и поскольку строки используются в пуле строк для повторного использования, вероятность того, что он останется в памяти в течение длительного времени, что создает угрозу безопасности. Поскольку любой, у кого есть доступ к дампу памяти, может найти пароль в ясном тексте
  • Рекомендация Java с использованием метода getPassword() JPasswordField, который возвращает метод char [] и устаревший getText(), который возвращает пароль в текстовом виде с указанием причины безопасности.
  • toString() всегда существует риск печати обычного текста в файле журнала или консоли, но если вы используете Array, вы не будете печатать содержимое массива, а его память будет распечатана.

    String strPwd = "passwd";
    char[] charPwd = new char[]{'p','a','s','s','w','d'};
    System.out.println("String password: " + strPwd );
    System.out.println("Character password: " + charPwd );
    

    Пароль строкой: passwd

    Пароль персонажа: [C @110b2345

Заключительные мысли: Хотя использование char [] не только достаточно, вам нужно стереть контент, чтобы быть более безопасным. Я также предлагаю работать с хешированным или зашифрованным паролем вместо обычного текста и освобождать его из памяти, как только будет завершена аутентификация.

  • 3
    «Поскольку любой, кто имеет доступ к дампу памяти, может найти пароль открытым текстом» Как я могу получить доступ к дампу памяти и найти там пароль?
  • 3
    @MohitKanwar Запустить дамп памяти через jmap или jvisualvm. Если установлено значение heapdumponoutofmemoryerror, вы можете запустить удаленный дамп кучи, вызвав состояние нехватки памяти. Получив дамп, вы можете просмотреть его с помощью jvisualvm или инструмента анализа памяти eclipse или инструментов командной строки и проверить все объекты и их значения.
73

Я не думаю, что это правильное предложение, но я могу хотя бы догадаться по этой причине.

Я думаю, что мотивация заключается в том, что вы можете быстро и достоверно стереть все следы пароля в памяти и с уверенностью после его использования. С помощью char[] вы можете перезаписать каждый элемент массива пустым или что-то точно. Вы не можете редактировать внутреннее значение String таким образом.

Но это одно не является хорошим ответом; почему бы не просто убедиться, что ссылка на char[] или String не исчезает? Тогда нет проблемы с безопасностью. Но дело в том, что объекты String могут быть intern() изложены в теории и сохранены в постоянном пуле. Я полагаю, что использование char[] запрещает эту возможность.

  • 2
    Я бы не сказал, что проблема в том, что ваши ссылки будут или не будут "убегать". Просто строки остаются неизмененными в памяти в течение некоторого дополнительного времени, в то время как char[] может быть изменено, и тогда не имеет значения, будет ли он собран или нет. И поскольку интернирование строк должно быть сделано явно для не-литералов, это то же самое, что сказать, что на char[] может ссылаться статическое поле.
  • 0
    пароль в памяти не является строкой из сообщения формы?
58

Ответ уже дан, но я хотел бы поделиться проблемой, которую я обнаружил в последнее время со стандартными библиотеками Java. Несмотря на то, что теперь они очень осторожно заменяют строки пароля char[] (что, конечно же, хорошо), другие важные критически важные данные, похоже, упускают из виду, когда дело доходит до очистки его от памяти.

Я имею в виду, например, класс PrivateKey. Рассмотрим сценарий, в котором вы бы загрузили частный ключ RSA из файла PKCS # 12, используя его для выполнения некоторой операции. Теперь в этом случае обнюхивание пароля само по себе не поможет вам, пока физический доступ к ключевому файлу будет надлежащим образом ограничен. Как атакующий, вам будет намного лучше, если вы получите ключ напрямую, а не пароль. Желаемая информация может быть пропущена много, дампы ядра, сеанс отладчика или файлы подкачки - вот лишь некоторые примеры.

И, как оказалось, нет ничего, что позволило бы очистить личную информацию от PrivateKey из памяти, потому что нет API, который позволяет стереть байты, которые формируют соответствующую информацию.

Это плохая ситуация, так как этот документ описывает, как это обстоятельство потенциально может быть использовано.

Библиотека OpenSSL, например, перезаписывает критические разделы памяти до освобождения секретных ключей. Поскольку Java собирает мусор, нам нужны явные методы для очистки и аннулирования личной информации для Java-ключей, которые должны применяться сразу же после использования ключа.

  • 0
    Одним из способов решения этой PrivateKey является использование реализации PrivateKey , которая фактически не загружает свой частный контент в память: например, через аппаратный токен PKCS # 11. Возможно, программная реализация PKCS # 11 могла бы позаботиться об очистке памяти вручную. Возможно, лучше использовать что-то вроде хранилища NSS (которое разделяет большую часть своей реализации с PKCS11 хранилища PKCS11 в Java). KeychainStore (хранилище ключей OSX) загружает все содержимое закрытого ключа в свои экземпляры PrivateKey , но в этом нет необходимости. (Не уверен, что делает WINDOWS-MY KeyStore в Windows.)
  • 0
    @ Bruno Конечно, аппаратные токены не страдают от этого, но как насчет ситуаций, когда вы более или менее вынуждены использовать программный ключ? Не каждое развертывание имеет бюджет, чтобы позволить себе HSM. Программные хранилища ключей в какой-то момент должны будут загрузить ключ в память, поэтому, по крайней мере, нам нужно, по крайней мере, дать возможность очистить память снова.
Показать ещё 2 комментария
46

Как утверждает Джон Скит, нет никакого способа, кроме как с помощью отражения.

Однако, если отражение является для вас вариантом, вы можете это сделать.

public static void main(String[] args) {
    System.out.println("please enter a password");
    // don't actually do this, this is an example only.
    Scanner in = new Scanner(System.in);
    String password = in.nextLine();
    usePassword(password);

    clearString(password);

    System.out.println("password: '" + password + "'");
}

private static void usePassword(String password) {

}

private static void clearString(String password) {
    try {
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        char[] chars = (char[]) value.get(password);
        Arrays.fill(chars, '*');
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}

при запуске

please enter a password
hello world
password: '***********'

Примечание: если String char [] был скопирован как часть цикла GC, есть вероятность, что предыдущая копия находится где-то в памяти.

Эта старая копия не появится в дампе кучи, но если у вас есть прямой доступ к необработанной памяти процесса, вы можете ее увидеть. В общем, вы должны избегать доступа любого пользователя.

  • 2
    Лучше также сделать что-нибудь, чтобы предотвратить печать длины пароля, которую мы получаем из '***********' .
  • 0
    @chux вы можете использовать символ нулевой ширины, хотя это может быть более запутанным, чем полезным. Невозможно изменить длину массива char без использования Unsafe. ;)
Показать ещё 3 комментария
38

Изменить: Возвращаясь к этому ответу после года исследований в области безопасности, я понимаю, что это приводит к довольно неприятным последствиям, что вы когда-либо сравнивали бы пароли открытого текста. Пожалуйста, не надо. Используйте безопасный односторонний хэш с солью и разумное количество итераций. Подумайте о том, как использовать библиотеку: это трудно понять!

Оригинальный ответ: Что касается того факта, что String.equals() использует оценку короткого замыкания и поэтому уязвим для временной атаки? Это может быть маловероятно, но теоретически вы можете сравнить время с паролем, чтобы определить правильную последовательность символов.

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        // Quits here if Strings are different lengths.
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            // Quits here at first different character.
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

Еще несколько ресурсов по таймингу:

  • 0
    Но это может быть и в сравнении char [], где-то мы будем делать то же самое и при проверке пароля. Так как же char [] лучше string?
  • 3
    Вы абсолютно правы, ошибку можно совершить в любом случае. Знание этой проблемы является наиболее важным здесь, учитывая, что в Java не существует явного метода сравнения паролей для паролей на основе строк или символов char []. Я бы сказал, что искушение использовать compare () для Strings - хорошая причина, чтобы использовать char []. Таким образом, вы, по крайней мере, можете контролировать, как выполняется сравнение (без расширения String, что очень болезненно).
Показать ещё 2 комментария
35

Это все причины, нужно выбрать массив char [] вместо String для пароля.

1. Поскольку строки являются неизменными в Java, если вы храните пароль в виде обычного текста, он будет доступен в памяти до тех пор, пока сборщик Garbage не очистит его, и поскольку String используется в пуле String для повторного использования, существует довольно высокая вероятность того, что он будет остаются в памяти в течение длительного времени, что создает угрозу безопасности.

Так как любой, кто имеет доступ к дампу памяти, может найти пароль в открытом тексте, это еще одна причина, по которой вы всегда должны использовать зашифрованный пароль, а не простой текст. Поскольку строки неизменяемы, невозможно изменить содержимое строк, потому что любое изменение приведет к созданию новой строки, а если вы используете char [], вы все равно можете установить все элементы как пустые или нулевые. Таким образом, сохранение пароля в массиве символов явно снижает риск безопасности при краже пароля.

2. Сама Java рекомендует использовать метод getPassword() JPasswordField, который возвращает char [] вместо устаревшего метода getText(), который возвращает пароли в ясном тексте с указанием соображений безопасности. Хорошо следовать рекомендациям команды Java и придерживаться стандартов, а не идти против них.

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("Character password: " + charPassword);

String password: Unknown
Character password: [C@110b053

Ссылка на этот блог. Надеюсь, это поможет.

  • 8
    Это избыточно. Этот ответ является точной версией ответа, написанного @SrujanKumarGulla stackoverflow.com/a/14060804/1793718 . Пожалуйста, не копируйте и не дублируйте один и тот же ответ дважды.
  • 0
    В чем разница между 1.) System.out.println («Символьный пароль:» + charPassword); и 2.) System.out.println (charPassword); Потому что он дает то же «неизвестное», что и вывод.
34

Нет ничего, что массив char дает вам vs String, если вы не очистите его вручную после использования, и я не видел, чтобы кто-то действительно делал это. Поэтому для меня предпочтение char [] vs String немного преувеличено.

Взгляните на широко используемую библиотеку Spring Security здесь и спросите себя - парни Spring Security некомпетентны или char [] пароли просто не имеют большого смысла. Когда какой-то неприятный хакер захватывает память вашей памяти, убедитесь, что она получит все пароли, даже если вы используете сложные способы скрыть их.

Тем не менее, Java все время меняется, и некоторые страшные функции, такие как Функция дедупликации строк Java 8 может ставить объекты String без вашего ведома. Но это разные разговоры.

  • 0
    Почему строковая дедупликация страшна? Это применимо только в том случае, если по крайней мере две строки имеют одинаковое содержимое, поэтому какая опасность может возникнуть, если эти две уже идентичные строки совместно используют один и тот же массив? Или давайте спросим наоборот: если нет дедупликации строк, какое преимущество возникает из-за того, что обе строки имеют отдельный массив (с одинаковым содержимым)? В любом случае будет существовать массив этого содержимого, по крайней мере, до тех пор, пока живая самая длинная строка этого содержимого ...
  • 0
    @ Держите все, что находится вне вашего контроля, - потенциальный риск ... например, если два пользователя имеют один и тот же пароль, эта замечательная функция будет хранить их обоих в одном символе [], давая понять, что они одинаковы, не уверен, что это так. огромный риск, но все же
Показать ещё 3 комментария
28

Строки неизменяемы и не могут быть изменены после их создания. Создание пароля в виде строки приведет к остаточному обращению к паролю в куче или в пуле строк. Теперь, если кто-то возьмет кучу кучи Java-процесса и тщательно проверит его, он сможет угадать пароли. Конечно, эти неиспользуемые строки будут собирать мусор, но это зависит от того, когда GC запускается.

С другой стороны char [] изменяются, как только выполняется аутентификация, вы можете перезаписать их любым символом, как все M или обратные слэши. Теперь даже если кто-то берет кучу кучи, он, возможно, не сможет получить пароли, которые в настоящее время не используются. Это дает вам больше контроля в том смысле, как очистка содержимого объекта самостоятельно или до ожидания выполнения GC.

  • 0
    Они будут только GC'd, если JVM в вопросе> 1.6. До 1.7 все строки хранились в permgen.
  • 0
    @avgvstvs: «все строки были сохранены в permgen» - это просто неправильно. Там хранились только интернированные строки, и если они не были получены из строковых литералов, на которые ссылается код, они все равно были собраны сборщиком мусора. Просто подумай об этом. Если в JVM до 1.7 строки обычно никогда не собирались GCed, как могло бы выжить какое-либо Java-приложение дольше нескольких минут?
Показать ещё 3 комментария
17

Короткий и простой ответ будет состоять в том, что char[] является изменяемым, а String объектов нет.

Strings в Java являются неизменяемыми объектами. Вот почему они не могут быть изменены после создания, и поэтому единственный способ удалить их содержимое из памяти - собрать их мусором. Это будет только тогда, когда память, освобожденная объектом, может быть перезаписана, и данные исчезнут.

Теперь сбор мусора в Java не происходит ни с каким гарантированным интервалом. Таким образом, String может сохраняться в памяти в течение длительного времени, и если процесс выйдет из строя в течение этого времени, содержимое строки может закончиться в дампе памяти или в каком-то журнале.

С помощью массива символов вы можете прочитать пароль, завершить работу с ним, как только сможете, а затем сразу же изменить содержимое.

  • 20
    Это просто бессмысленная перефразировка ответа Скита.
  • 0
    @fallenidol Совсем нет. Читайте внимательно, и вы найдете различия.
16

1) Так как Строки неизменны в Java, если вы храните пароль как обычный текст, он будет доступен в памяти до тех пор, пока сборщик мусора не очистит его, и поскольку String используется в пуле String для повторного использования, существует довольно высокая вероятность того, что он будет остаются в памяти в течение длительного времени, что создает угрозу безопасности. Поскольку любой, у кого есть доступ к дампу памяти, может найти пароль в открытом тексте, и по этой причине вы всегда должны использовать зашифрованный пароль, чем обычный текст. Поскольку строки являются неизменными, невозможно изменить содержимое строк, потому что любое изменение приведет к созданию новой строки, а если вы char [], вы все равно можете установить весь его элемент как пустой или нулевой. Таким образом, хранение пароля в массиве символов снижает риск безопасности при краже пароля.

2) Сама Java рекомендует использовать метод getPassword() JPasswordField, который возвращает char [] и устаревший метод getText(), который возвращает пароль в ясном тексте с указанием причины безопасности. Хорошо следовать советам команды Java и придерживаться стандарта, а не идти против него.

14

Строка неизменна и идет в пул строк. После написания это нельзя перезаписать.

char[] - это массив, который вы должны перезаписать после того, как вы использовали пароль, и вот как это должно быть сделано:

char[] passw = request.getPassword().toCharArray()
if (comparePasswords(dbPassword, passw) {
 allowUser = true;
 cleanPassword(passw);
 cleanPassword(dbPassword);
 passw=null;
}

private static void cleanPassword (char[] pass) {
 for (char ch: pass) {
  ch = '0';
 }
}

Один сценарий, в котором злоумышленник может использовать его, - это crashdump - когда JVM падает и генерирует дамп памяти - вы сможете увидеть пароль.

Это не обязательно злонамеренный внешний злоумышленник. Это может быть пользователь службы поддержки, который имеет доступ к серверу для целей мониторинга. Он мог заглянуть в аварийный диск и найти пароли.

  • 1
    ch = ноль; ты не можешь сделать это
  • 0
    @Yugerten хорошая мысль. Это просто псевдокод, но да
12

Строка в java неизменна. Поэтому всякий раз, когда создается строка, она остается в памяти до тех пор, пока не будет собрана мусор. Поэтому любой, кто имеет доступ к памяти, может прочитать значение строки.
Если значение строки будет изменено, это приведет к созданию новой строки. Таким образом, как исходное значение, так и измененное значение остаются в памяти, пока не будет собран мусор.

С помощью массива символов содержимое массива может быть изменено или удалено после того, как будет применена цель пароля. Исходное содержимое массива не будет найдено в памяти после его модификации и даже до того, как будет запущена сборка мусора.

Из-за проблемы безопасности лучше хранить пароль в виде массива символов.

0

Использование пароля в String или Char [] всегда является спорным, потому что оба подхода имеют свою собственную полезность и недостаток. Это зависит от потребности, которую пользователь ожидает выполнить. Ниже строки могут помочь лучше понять, когда использовать этот контейнер: поскольку String в java неизменен, всякий раз, когда кто-то пытается манипулировать вашей строкой, он создает новый Object и существующий остается без изменений. Это можно рассматривать как преимущество для хранения пароля как String, но с другой стороны. Объект String остается в памяти даже после использования. Так что, если кто-нибудь получит место в памяти, вы сможете легко отслеживать свой пароль, хранящийся в этом месте. Придя к Char [], который изменен, но он имеет преимущество, что после использования программист может Explicilty очистить массив или переопределить значения. Так что после того, как он не используется, он очищается, и никто не может знать о том, что вы сохранили.

Исходя из вышеприведенных обстоятельств, можно получить идею о том, следует ли идти со String или Char [] по их требованию.

Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню