33

I know that in order to delete a Java object I should use character array instead of String, since I can safely erase (rewrite the character array with other data) its content. This seems not to be feasible for the String objects.

Now on BlackBerry which is Java based, I was not able to find an API to handle data as character array but i am obliged to use String. Thus my question, in case I store a password in an object, how can I securely delete it?

1
  • What are you confused about? What type of references are you expecting?
    – this.josh
    Commented Sep 9, 2011 at 8:20

4 Answers 4

44
+50

Actually you cannot really "safely erase" an array of characters in Java. Java does memory allocation through a garbage collector, a tricky piece of software which, in practice, will move memory objects in physical RAM on a regular basis. So what you think as "a char[] instance" will be copied in several places, and the erasure will physically happen only in one of those places.

In that context, "secure deletion" cannot really exist in Java. If you use Java, you must ensure that the usage context is such that secure deletion is unnecessary: "secure deletion" is needed mostly when the OS may allocate non-zeroized RAM blocks (thus an application may get excerpts of old RAM from other applications), or in the presence of virtual memory (parts of the RAM being copied to a hard disk). I guess that these do not apply to a BlackBerry, so simple String instances ought to be fine.

An other way to state it is that if String instance are not fine for passwords, then you have bigger security issues than mere password leakage. After all, you use a password to protect access to some data, so if you need "secure erasing" for a password, then, quite logically, you would also need "secure erasing" for the protected data as well, and everything you do with it.

(One can guess that I am not a big fan of the concept of "secure erasing".)

17
  • 2
    I suppose Java doesn't have anything along the lines of a SecureString class like in .NET? msdn.microsoft.com/en-us/library/…
    – Steve
    Commented Sep 1, 2011 at 13:51
  • 1
    @Jim, the answer is "No, that does not securely erase the password". Read Thomas's answer again; he already answered your question. Garbage collectors can make copies of the data underneath you, so there may be other copies of the data still laying around.
    – D.W.
    Commented Sep 1, 2011 at 19:51
  • 4
    @Jim: no, @DW is right (well, of course, since he mostly says that I am right, so I will not contradict him). The problem is due to the fact that a Java object, any Java object, even a char[], will be copied around in physical RAM. At the Java level, you only see the most recent copy, and when you erase your array, the older copies are unaffected (they are "unallocated memory" which may be used for other allocations, but they still did not get erased). Commented Sep 2, 2011 at 9:06
  • 1
    @Thomas:Ok, I'll "buy" that ;) But how do you explain the post of SUN that actually suggest this (the clearing of char[]) for safety reason?Also taking into account that they have many APIs related to security e.g. load a Keystore take as input for password a char[] and not a String object?
    – Jim
    Commented Sep 2, 2011 at 15:32
  • 3
    @Jin: older (much older) versions of the JVM used a conservative GC which was not moving objects around -- on those systems, programmatic erasure has a chance of having the intended result. So this began a tradition of using char[] for passwords. Also, erasure is most pertinent on systems where "old memory" can leak towards other applications, as in Windows 98, but this is much less relevant now. As of 2011, passwords as char[] are kept for the sake of tradition, and compatibility with older API. Commented Sep 2, 2011 at 15:38
6

in case I store a password in an object, how can I securely delete it?

I think you mean; how can you prevent an attacker with access to the device from recovering the password?

It depends on what level of access the attacker has gained.

If the attacker is limited to the external API you provide (not a good assumption), then access control using java.security.AccessController should suffice. If you design your access controls correctly (very difficult to do) and the attacker can not bypass the access controls, then access control will prevent the attacker from obtaining the data.

If the attacker is limited to operating within the Java virtual machine but not your API, the you need to protect the data with KeyStore.PrivateKeyEntry. At this level you can not rely on the proper operation of your design to protect the data and you must rely on the Java virtual machine to provide protection.

If the attacker is limited to the operating system (not the Java virtual machine) then you can not protect your data. If the attacker can prevent the Java Virtual machine from operating as designed, then the attacker can bypass any Java security mechanism.

If the attacker has physical access to the device it is impossible to protect the data against all attacks. At this level the attacker can read data as it is being written to RAM, flash, hardware modules, etc.

3
  • can you elaborate a little more on what special protection the Java Virtual Machine provides for KeyStore.PrivateKeyEntry (I assume you mean java.security.KeyStore.PrivateKeyEntry)? I wasn't able to find any info on that. Thanks!
    – jbyler
    Commented May 12, 2014 at 23:26
  • @jbyler From Java Cryptography Architecture (JCA) "The KeyStore class supplies well-defined interfaces to access and modify the information in a keystore." The exact protection depends on the Java implementation: Oracle/Sun, Android, or other.
    – this.josh
    Commented May 21, 2014 at 6:48
  • 1
    OK, thanks Josh. I think the KeyStore is, as that quote suggests, just an API for manipulating a keystore. There's no special protection provided by the JVM; instances of a KeyStore.PrivateKeyEntry are subject to the same copying and garbage collection characteristics as other Java objects. So you might as well just use a String to hold the password, as suggested in the answer from @thomas-pornin.
    – jbyler
    Commented May 22, 2014 at 18:26
-1

You're right. As you pointed out, the lifecycle of objects (such as immutable strings) is managed by the garbage collector. So if sensitive information is in a string, you cannot overwrite the sensitive data. Also, the lifecycle of an array is managed by the garbage collector, but you can overwrite the contents, so if you overwrite the contents with random data (or zeroes), you 'delete' the contents.

Looking at the BlackBerry site [1], it actually seems that their JVM supports char[] arrays. If - for unclear reasons - this basic construct is not available from the BlackBerry JVM, you should store your confidential bits in a byte[] array which you overwrite post usage.

[1] http://supportforums.blackberry.com/t5/Java-Development/How-to-convert-Byte-Array-to-char-Array/td-p/252772

-1

If we don't try to delete it but override it with meaningless value, it is easier. Even string.value can be override by useless char set.

2
  • 1
    Be aware that assigning a new value to a string object does not necessarily overwrite it. The old one could still be available until the garbage collection decides to clean it up.
    – Jens Erat
    Commented May 10, 2015 at 14:59
  • Strings in Java are immutable. Commented Mar 30, 2018 at 23:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .