Categories
char java passwords security string

Why is char[] preferred over String for passwords?

3727

In Swing, the password field has a getPassword() (returns char[]) method instead of the usual getText() (returns String) method. Similarly, I have come across a suggestion not to use String to handle passwords.

Why does String pose a threat to security when it comes to passwords?
It feels inconvenient to use char[].

0

    4631

    Strings are immutable. That means once you’ve created the String, if another process can dump memory, there’s no way (aside from reflection) you can get rid of the data before garbage collection kicks in.

    With an array, you can explicitly wipe the data after you’re done with it. You can overwrite the array with anything you like, and the password won’t be present anywhere in the system, even before garbage collection.

    So yes, this is a security concern – but even using char[] only reduces the window of opportunity for an attacker, and it’s only for this specific type of attack.

    As noted in the comments, it’s possible that arrays being moved by the garbage collector will leave stray copies of the data in memory. I believe this is implementation-specific – the garbage collector may clear all memory as it goes, to avoid this sort of thing. Even if it does, there’s still the time during which the char[] contains the actual characters as an attack window.

    21

    • 28

      If a process has access to memory of your application, then that is already a security breach, right?

      – Yeti

      Sep 1, 2015 at 11:26

    • 25

      @Yeti: Yes, but it’s not like it’s black and white. If they can only get a snapshot of the memory then you want to reduce how much damage that snapshot can do, or reduce the window during which a really serious snapshot can be taken.

      – Jon Skeet

      Sep 1, 2015 at 11:47

    • 59

      A common attack method is to run a process that allocates lots of memory and then scans it for left-over, useful data like passwords. The process doesn’t need any magical access to another process’s memory space; it just relies on other processes dying without first clearing out sensitive data and the OS also not clearing memory (or page buffers) before making it available to a new process. Clearing out passwords stored in char[] locations cuts off that line of attack, something not possible when using String.

      – Ted Hopp

      Sep 5, 2016 at 19:11


    • 14

      If OS does not clear memory before giving it to another process, the OS has major security issues! However, technically the clearing is often done with protected mode tricks and if the CPU is broken (e.g. Intel Meldown) it’s still possible to read old memory contents.

      Apr 21, 2020 at 7:33

    • 10

      @PrateekPande: It would only be in the literal pool if it were present in the source code, or explicitly interned. Those are both bad ideas in general…

      – Jon Skeet

      Jan 10, 2021 at 12:35

    1311

    While other suggestions here seem valid, there is one other good reason. With plain String you have much higher chances of accidentally printing the password to logs, monitors or some other insecure place. char[] is less vulnerable.

    Consider this:

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

    Prints:

    String: Password
    Array: [[email protected]
    

    11

    • 49

      @voo, but i doubt you’d log via direct writing to stream and concatenation. logging framework would transform the char[] into good output

      – bestsss

      Jan 18, 2012 at 1:14

    • 47

      @Thr4wn Default implementation of toString is [email protected]. [C represents char[], the rest is hexadecimal hash code.

      Jan 20, 2012 at 12:39

    • 20

      Interesting idea. I would like to point out that this does not transpose to Scala which has a meaningful toString for arrays.

      – mauhiz

      Jul 9, 2015 at 8:36

    • 45

      I’d write a Password class type for this. It’s less obscure, and harder to accidentally pass somewhere.

      – user1804599

      Aug 31, 2015 at 17:32


    • 12

      Why would someone assume the char array was going to be cast as an Object? I’m not sure I get why every likes this answer. Suppose you did this: System.out.println(“Password”.toCharArray());

      – GC_

      Aug 22, 2016 at 13:23

    734

    To quote an official document, the Java Cryptography Architecture guide says this about char[] vs. String passwords (about password-based encryption, but this is more generally about passwords of course):

    It would seem logical to collect and store the password in an object
    of type java.lang.String. However, here’s the caveat: Objects of
    type String are immutable, i.e., there are no methods defined that
    allow you to change (overwrite) or zero out the contents of a String
    after usage. This feature makes String objects unsuitable for
    storing security sensitive information such as user passwords. You
    should always collect and store security sensitive information in a
    char array instead.

    Guideline 2-2 of the Secure Coding Guidelines for the Java Programming Language, Version 4.0 also says something similar (although it is originally in the context of logging):

    Guideline 2-2: Do not log highly sensitive information

    Some information, such as Social Security numbers (SSNs) and
    passwords, is highly sensitive. This information should not be kept
    for longer than necessary nor where it may be seen, even by
    administrators. For instance, it should not be sent to log files and
    its presence should not be detectable through searches. Some transient
    data may be kept in mutable data structures, such as char arrays, and
    cleared immediately after use. Clearing data structures has reduced
    effectiveness on typical Java runtime systems as objects are moved in
    memory transparently to the programmer.

    This guideline also has implications for implementation and use of
    lower-level libraries that do not have semantic knowledge of the data
    they are dealing with. As an example, a low-level string parsing
    library may log the text it works on. An application may parse an SSN
    with the library. This creates a situation where the SSNs are
    available to administrators with access to the log files.

    5

    • 5

      this is exactly the flawed/bogus reference I talk about below Jon’s answer, it’s a well known source w/ a lot of criticism.

      – bestsss

      Jan 22, 2012 at 20:45

    • 44

      @bestass can you please also cite a reference?

      Aug 11, 2012 at 11:27

    • 16

      @bestass sorry, but String is pretty well understood and how it behaves in the JVM… there are good reasons to use char[] in place of String when dealing with passwords in a secure manner.

      – SnakeDoc

      Jun 27, 2014 at 0:50

    • 4

      once again though the password is passed as a string from the browser to the request as ‘string’ not char? so no matter what you do it’s a string, at which point it should be acted on and discarded, never stored in memory?

      – Dawesi

      Aug 5, 2018 at 19:50

    • 5

      @Dawesi – At which point – that’s application specific, but the general rule is to do so as soon as you get a hold of something that is supposed to be a password (plaintext or otherwise). You get it from the browser as part of an HTTP request, for instance. You cannot control the delivery, but you can control your own storage, so as soon as you get it, put it in a char[], do what you need to do with it, then set all to ‘0’ and let the gc reclaim it.

      Jan 3, 2019 at 19:25