Obfuscation: hide hardcoded values in java [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
hiding strings in Obfuscated code
I'm trying to hide a little some static Strings of my app in order to make it harder to decompile, this way like the constants like cipher algorithms names are harder to find in the obfuscated code.
I've considered things like:
String CONCAT= "concat"+"string";
String RAW_STRING= "raw_string";
String FROM_BYTES=new String("from_bytes".getBytes());
String FROM_CHARS=new String(new char[]{'f','r','o','m','_','c','h','a','r','s'});
String FROM_CHAR2=new String(new char[]{102,114,111,109,95,99,104,97,114,115,95,50});
And the last two options seems to be "darker" than the raw option but I imagine there are better ways for doing this.
How can I improve this? Thanks

For one, you shouldn't just write
String FROM_CHAR2=new String(new char[]{102,114,111,109,95,99,104,97,114,115,95,50});
It's a dead give-away that the char array is actually a String.
You can do a combination of the followings:
put your "String" in an int[] array
or even better, break your String into several int arrays
calculate/manipulate the array's values at various stage of the application, so its value will only become valid at a certain interval during a runtime, guaranteeing that it won't be deciphered at a curious glance by decompiling your code
passes the array(s) back and forth, through local variables, back to instance variables, etc, before finally converting the arrays to a single array to be passed to the String constructor
immediately set the String to null after use, just to reduce the amount of time the actual String exist at runtime

I would prefer to set the value in the static (class) initializer using an decryption algo
Something like
class ...
String CONCAT;
static {
CONCAT = uncrypt ("ahgsdhagcf");
}
where uncrypt might be really a good unencryption algo or somewhat weaker a base64 decode.
In any case you need a simple program to encode your string first.

Related

Is there any scenario where character array is better than Strings in Java

I feel strings can replace character array in all the scenarios. Even considering the immutability characteristic of Strings, declaration of strings in appropriate scope and java's garbage collection feature should help us avoid any memory leaks. I want to know if there is any corner case where character array should be used instead of Strings in Java.
Character arrays have some slight advantage over plain strings when it comes to storing security sensitive data. There's a lot of resources on that, for example this question: Why is char[] preferred over String for passwords? (with an answer by Jon Skeet himself).
In general it boils down to two things:
You have very little influence on how long a String stays in memory. Because of that you might leak sensitive data through a memory dump.
Leaking sensitive data accidentally in application logs as clear text is much more likely with plain strings
More reading:
Why we read password from console in char array instead of String
https://www.codebyamir.com/blog/use-character-arrays-to-store-sensitive-data-java
https://www.geeksforgeeks.org/use-char-array-string-storing-passwords-java/amp/
https://www.baeldung.com/java-storing-passwords
https://javarevisited.blogspot.com/2012/03/why-character-array-is-better-than.html
https://javainsider.wordpress.com/2012/12/10/character-array-is-better-than-string-for-storing-password-in-java/amp/
String is a class, not a build in type. It most likely does what it does by using a char array underneath, but there is no guarantee. "We dont care how it is implemented". It has methods that make sense for strings, like comparing strings. Comparing arrays?? Hmm. Doesn't really make sense to do it. You could check if they are equal sure, but less or greater than...
Back in point. One scenario is you want to operate with chars, not a string. For example you have letters of the alphabet and want to sort them. Or grades in A-F system and you want to sort them. Generally where it makes sense having chars that are not connected to have some meaning together (like in a message string, or a text message). You would not generally need to sort the chars of a text message now, would you? So, you use an array.
To sort, you can take advantage of the Arrays.sort() method for example, while i dont think there is a method that does it for strings. Perhaps 3rd part libraries.
On another note(unrelated to question) , you can use StringBuilder to if you want to modify strings often. Its better at performace.
You don't have to look much further than at methods in the JDK core API that use char[].
Such as this one (java.io.Reader):
public int read(char[] cbuf)
throws IOException
Reads characters into an array. This method will block until some input is available, an I/O error occurs, or the end of the stream is reached.
Parameters:
cbuf - Destination buffer
Returns:
The number of characters read, or -1 if the end of the stream has been reached
Throws:
IOException - If an I/O error occurs
Instead of returning a String they ask you to pass in a char[] to use as a buffer to write the result into. The reason is efficiency.
You might be knowing String is immutable and how Substring can cause memory leak in Java.
Since Strings are immutable in Java if you store password as plain text it will be available in memory until Garbage collector clears it and since String are used in String pool for reusability there is pretty high chance that it will be remain in memory for long duration, which pose a security threat. Since any one who has access to memory dump can find the password in clear text. Since Strings are immutable there is no way contents of Strings can be changed because any change will produce new String, while if you char[] you can still set all his element as blank or zero. So Storing password in character array clearly mitigates security risk of stealing password.

String.valueOf(someVar) vs ("" + someVar) [duplicate]

This question already has answers here:
String valueOf vs concatenation with empty string
(10 answers)
Closed 5 years ago.
I want to know the difference in two approaches. There are some old codes on which I'm working now, where they are setting primitive values to a String value by concatenating with an empty String "".
obj.setSomeString("" + primitiveVariable);
But in this link Size of empty Java String it says that If you're creating a separate empty string for each instance, then obviously that will take more memory.
So I thought of using valueOf method in String class. I checked the documentation String.valueOf() it says If the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.
So which one is the better way
obj.setSomeString("" + primitiveVariable);
obj.setSomeString(String.valueOf(primitiveVariable));
The above described process of is done within a List iteration which is having a size of more than 600, and is expected to increase in future.
When you do "" that is not going to create an Object. It is going to create a String literal. There is a differenc(How can a string be initialized using " "?) actually.
Coming to your actual question,
From String concatenation docs
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.
So unnecissarly you are creating StringBuilder object and then that is giving another String object.
However valueOf directly give you a String object. Just go for it.
Besides the performance, just think generally. Why you concatenating with empty string, when actually you want to convert the int to String :)
Q. So which one is the better way
A. obj.setSomeString(String.valueOf(primitiveVariable)) is usually the better way. It's neater and more domestic. This prints the value of primitiveVariable as a String, whereas the other prints it as an int value. The second way is more of a "hack," and less organized.
The other way to do it is to use Integer.toString(primitiveVariable), which is basically the same as String.valueOf.
Also look at this post and this one too

String and string buffer memory concept [duplicate]

This question already has answers here:
Python equivalent of Java StringBuffer?
(10 answers)
Closed 8 years ago.
Java has string and string buffer concept.
Is there any concept of string buffer available in python?
Depends on what you want to do. If you want a mutable sequence, the builtin list type is your friend, and going from str to list and back is as simple as:
mystring = "abcdef"
mylist = list(mystring)
mystring = "".join(mylist)
If you want to build a large string using a for loop, the pythonic way is usually to build a list of strings then join them together with the proper separator (linebreak or whatever).
Else you can also use some text template system, or a parser or whatever specialized tool is the most appropriate for the job.
this link might be useful for concatenation in python
http://pythonadventures.wordpress.com/2010/09/27/stringbuilder/
example from above link:
def g():
sb = []
for i in range(30):
sb.append("abcdefg"[i%7])
return ''.join(sb)
print g()
# abcdefgabcdefgabcdefgabcdefgab

Java: Console class [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is char[] preferred over string for passwords?
Reading the java documentation, i found this statement about Console class
First, it suppresses echoing, so the password is not visible on the user's screen. Second, readPassword returns a character array, not a String, so the password can be overwritten, removing it from memory as soon as it is no longer needed.
Why a character array can be overwritten and a String not?
Or maybe a character array can be overwritted in a more simple way?
A String could be kept in something called a String pool by the JVM to manage memory usage for Strings more efficiently. A side effect of this however, is that it may be kept in memory even after you overwrite the reference with a new String.
A character array however can be directly overwritten, and is therefore safer in this respect.
From the Sun Certified Java Programmer for Java 6 Study Guide:
the readPassword method doesn't return a string: it returns a character array. Here's the reason for this: Once you've got the password, you can verify it and then absolutely remove it from memory. If a string was returned, it could exist in a pool somewhere in memory and perhaps some nefarious hacker could find it.

Why char[] performs better than String ?- Java

In reference to the link: File IO Tuning, last section titled "Further Tuning" where the author suggests using char[] to avoid generating String objects for n lines in the file, I need to understand how does
char[] arr = new char{'a','u','t','h', 'o', 'r'}
differ with
String s = "author"
in terms of memory consumption or any other performance factor? Isn't String object internally stored as a character array? I feel silly since I never thought of this before. :-)
In Oracle's JDK a String has four instance-level fields:
A character array
An integral offset
An integral character count
An integral hash value
That means that each String introduces an extra object reference (the String itself), and three integers in addition to the character array itself. (The offset and character count are there to allow sharing of the character array among String instances produced through the String#substring() methods, a design choice that some other Java library implementers have eschewed.) Beyond the extra storage cost, there's also one more level of access indirection, not to mention the bounds checking with which the String guards its character array.
If you can get away with allocating and consuming just the basic character array, there's space to be saved there. It's certainly not idiomatic to do so in Java though; judicious comments would be warranted to justify the choice, preferably with mention of evidence from having profiled the difference.
In the example you've referred to, it's because there's only a single character array being allocated for the whole loop. It's repeatedly reading into that same array, and processing it in place.
Compare that with using readLine which needs to create a new String instance on each iteration. Each String instance will contain a few int fields and a reference to a char[] containing the actual data - so it would need two new instances per iteration.
I'd usually expect the differences to be insignificant (with a decent GC throwing away unused "young" objects very efficiently) compared with the IO involved in reading the data - assuming it's from disk - but I believe that's the point the author was trying to make.
The author didn't get the reason right. The real overhead in in.readLine() is the copying a char[] buffer when making a String out of it. The additional copying is the most damning cost when dealing with large data.
It is possible to optimize this within JDK so that the additional copying is not needed.
Here are few reasons which makes sense to believe that character array is better choice in Java than String:
Say for Storing the Password
1) Since Strings are immutable in Java, if you store password as plain text it will be available in memory until Garbage collector clears it and since String are used in String pool for reusability there is pretty high chance that it will be remain in memory for long duration, which pose a security threat.
Since any one who has access to memory dump can find the password in clear text and that's another reason you should always used an encrypted password than plain text.
Since Strings are immutable there is no way contents of Strings can be changed because any change will produce new String, while if you char[] you can still set all his element as blank or zero. So Storing password in character array clearly mitigates security risk of stealing password.
2) Java itself recommends using getPassword() method of JPasswordField which returns a char[] and deprecated getText() method which returns password in clear text stating security reason. Its good to follow advice from Java team and adhering to standard rather than going against it.
3) With String there is always a risk of printing plain text in log file or console but if use Array you won't print contents of array instead its memory location get printed. though not a real reason but still make sense.
For this simple program
String strPassword="Unknown";
char[] charPassword= new char[]{'U','n','k','n','o','w','n'};
System.out.println("String password: " + strPassword);
System.out.println("Character password: " + charPassword);
Output:
String password: Unknown
Character password: [C#110b053
That's all on why character array is better choice than String for storing passwords in Java. Though using char[] is not just enough you need to erase content to be more secure.
Hope this will help.
My answer is going to focus on other stack questions along this similar line, others have already posted more direct answers.
There have been other questions similar to this, advice seems to go along the lines of using StringBuilder.
If you're concerned with string concentenation this have a look at the performance as described here between three different implementations. With another stack post which can give you some additional pointers and examples you could try yourself to see the performance.

Categories

Resources