3

The below class is my security key provider for encryption.

public class MySecretKey {
private String key="2sfdsdf7787fgrtdfg#$%@cj5";
...
//Some Util methods goes on  Here .
}

First I didn't belive that one can access the private data without a getter, but, My goodness, I am able to see the key in the console now .

And somewhere else using reflection we can see the code like below :

public static void main(String[] args) throws Exception {
        Stacker myClass = new Stacker();
        Field key= myClass.getClass().getDeclaredField("key");
        field1.setAccessible(true);
        System.out.println(key.get(myClass));
    }

How can I hide my key from outside my class :( ,even private keyword also not helping me in case of Reflection.

Please give me some hint .

Thanks in advance.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • possible duplicate of [Java reflection framework and security](http://stackoverflow.com/questions/2652632/java-reflection-framework-and-security) – Luiggi Mendoza Feb 15 '13 at 21:07
  • 4
    Your key would be available in the compiled code anyways... – Alex DiCarlo Feb 15 '13 at 21:08
  • 1
    Yup. There's no way to keep data compiled into your code like that secure. Step one of the proper solution, however, is _not to compile your code together with untrusted code._ – Louis Wasserman Feb 15 '13 at 21:09
  • 1
    I thought of the encryption key as just one _example_ of a private field that can be accessed with reflection and setAccesible(true). There have been a few cases where I subclassed a library class, but I needed access to the superclass's private field for proper execution, e.g. a HashMap, so I used this reflection trick. Of course encryption keys should never reside in code, but I think that there are other cases where this trick merely breaks encapsulation, not security. In short, this question is about preventing the reflection trick, not securing an encryption key. +1 – rgettman Feb 15 '13 at 21:18
  • I think, in general, information hiding (using private/protected/etc. members) is a trick to help prevent bugs and to help prevent poor code design; not as a security measure. I.e. it might stop bad (as in foolish) code from being written, not bad (as in malicious) code from being executed. – Nick Feb 15 '13 at 21:27

4 Answers4

1

The preferred solution is to store the key in a file, and then use file system permissions to restrict access to the file. It's not a perfect solution (certainly not as convenient) but it's better than hardwiring the key in the code.

jdigital
  • 11,926
  • 4
  • 34
  • 51
1

All the strings defined in a Java class can be easily inspected by opening the class file in a hexadecimal editor, they're not, by any means, hidden. not to mention that they can be retrieved programatically using reflection, as you just discovered.

The mechanism you're using for "hiding" a private key is broken, and utterly flawed. You should instead store the key in an external file, for example a serialized, encrypted key store, protected by other means - for example, a password or another key stored elsewhere.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • This is a good point, but object inviolability is still relied on to protect one-time secrets obtained from a `SecureRandom` after class load. I don't think the OP excludes that use case. – Mike Samuel Feb 15 '13 at 21:30
  • 1
    This is just moving the problem forward... where do you hide the password used to uncipher the private key holder ? – poussma Jan 21 '14 at 09:10
1

setAccessible says

First, if there is a security manager, its checkPermission method is called with a ReflectPermission("suppressAccessChecks") permission.

so you can prevent this by denying the suppressAccessChecks permission.

Really though, it'd be better to avoid relying on the JVM to preserve object inviolability. Joe-E allows for mutual-suspicion between classes within a JVM, but the JVM wasn't designed for that.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
1

Easy, Make this class non-instantiatable How?

Make a private constructor and make your key field static

So your class will look like this

public class MySecretKey {
    public static String key="2sfdsdf7787fgrtdfg#$%@cj5";
    private MySecretKey(){} //Private constructor
    //No Util methods will go here.
}
Daksh Gargas
  • 3,498
  • 2
  • 23
  • 37