please am working on app that store sensitive user data on a database upon googling on how to do the answers point me to cwac saferoom since am using room for my database but the problem am facing are:
Cwac saferoom required i pass in an edittable object meani g the same method i call on edittext to get the input string as passphrase i dont really know how make a that object out of a string
How do i safely store the password on the device also
Please am using java
Cwac saferoom required i pass in an edittable object
Quoting the documentation: "The SafeHelperFactory constructor takes a either a byte[] or a char[] for the passphrase.". There is a utility method that takes an Editable, for the recommended path of getting the passphrase from the user. So, just create a SafeHelperFactory object via the constructor:
SafeHelperFactory factory = new SafeHelperFactory(thePassphraseFromTheUser);
i dont really know how make a that object out of a string
It is not a good idea to have a passphrase in a String. See:
https://www.sjoerdlangkemper.nl/2016/05/22/should-passwords-be-cleared-from-memory/
Why is char[] preferred over String for passwords?
But, for tests and stuff, call toCharArray() on your String to get a char[] to pass to the SafeHelperFactory constructor:
SafeHelperFactory factory = new SafeHelperFactory(stringPassphraseFromTheUser.toCharArray());
How do i safely store the password on the device also
Generally, you don't. You get the passphrase from the user.
If your minSdkVersion is 23 or higher, you could use androidx.security:security-crypto classes to store a generated passphrase in hardware-encrypted storage.
Related
I'm a software engineer building an Android App that will be used by a government agency.
One requirement in our contract is that the app must be FIPS 140 compliant.
https://en.wikipedia.org/wiki/FIPS_140
To be FIPS compliant our app must zeroize and clear any password objects in RAM, when the android app is closed. (By zeroing and clearing the password from RAM, we reduce the window of opportunity for attackers. i.e. this mitigates cold-boot attack risk: https://en.wikipedia.org/wiki/Cold_boot_attack)
To satisfy this requirement, we initially followed the advice in the following two SO posts to capture the user password as a CharArray instead of a string
Why is char[] preferred over String for passwords?
Getting a char array from the user without using a String
//First collect the password from Edit Text as a []char
int pl = passwordEditText.length();
char[] password = new char[pl];
passwordEditText.getText().getChars(0, pl, password, 0);
//Now set the password on viewmodel
viewModel.setPassword(password)
Once we have the password, we use it to call a 3rd party webservice library that fetches data for display on the screen.
ViewModel pseudocode:
public DataObject getData(char[] password){
return this.webService.getData(password);
}
When the user is done with our app, we call the following method to zeroize and clear the password
ViewModel pseudocode:
public zeroPassword(){
Arrays.fill(this.password, 0);
this.password = null;
}
This is all fine and dandy because char arrays in java are passed by reference (unlike Strings that are immutable), and we effectively zeroize any trace of the password character array from memory in the zeroPassword method.
HOWEVER...
We dug into the 3rd party WebService code (this.webService.getData(password))
and it turns out that under the covers, the webservice converts the char array password into a string, and then passes it around before making a network call.
Basically - Even though we zeroize the char array reference in our Android ViewModel code, because the char array is taken by a 3rd party lib and used to create a string, the Password will still exist in memory :(
OPTIONS
At this point we're considering two options:
Option 1 is to get a copy of the third party library and modify it so that it doesn't work with password strings. This way we can change any password string usage to use char arrays, buffers etc - all objects that we can zeroize at some point)
Option 2 - We investigate some way to zeroize and clear all memory pages used by our android app (i.e. shut down the whole app and clear RAM), when the user closes the app.
As a team we prefer option 2 because it would cover all of our bases. Option 1 will be challenging, invasive, time consuming, and messy.
UPDATE - Based on the answer here, it seems like Option 1 wont even actually work How can I ensure the destruction of a String object in Java?
Java uses generational garbage collection, and copies objects all over the place, even char arrays, so zeroing char arrays isn't guaranteed to remove the password from RAM.
Is there a way to accomplish what we've been asked to do? i.e. fully wipe any trace of the password from memory?
Can android security experts please opine?
Thanks
According to ViewModel Docs:
When the owner activity is finished, the framework calls the ViewModel
objects's onCleared() method so that it can clean up resources.
You don't need to manually create/call destructor to clean up ViewModel resources, because this lifecycle component already has a mechanism to clean-up its own resources.
To make it easier to understand, ViewModel has the following behavior:
When Activity is re-created on configuration changes: we still have the same ViewModel instance.
When Activity is finished: ViewModel will automatically call onCleared() to cleanup resources for us, so we don’t even have to do manual unbind/clean-up.
The reason why some ViewModel object still exist in the memory is because the Activity (which has the ViewModel) is still active, OR there might be another class which holds reference to this Activity.
Using V8 to run a service worker at app shutoff, for example something like:
addEventListener("fetch", event => {
event.respondWith(fetchAndReplace(event.request));
});
async function fetchAndReplace(request) {
const response = await fetch(request);
let type = response.headers.get("Content-Type") || "";
if (!type.startsWith("application/")) {
return response;
}
let newHeaders = new Headers(response.headers);
newHeaders.set('Clear-Site-Data', '"cache", "cookies", "storage",
"executionContexts"');
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
});
}
See Clear-Site-Data on MDN. "Site" is misleading as "site" ~= only websites.
I've been checking memory information dumping data hold in memory and I've seen a JSON structure of the request I use for login to the server.
For security reasons that information shouldn't be hold in memory so I've had to find out what is storing these data.
I tried to check OKHttp3 for avoiding caching any info but seems it could be GSON Converter.
this line https://github.com/square/retrofit/issues/2305 is from a guy complaining about Strings hold in memory.
I'd like to know if I could be right thinking about GSON as the problem and if there is any chance to let GSON know that I don't want to cache a concrete class.
Thanks
I think the problem is here :
There is two ways to add string in the string pool.
first if you declare your string literal like below, the string will add to pool.
String test = "test"
second if you call intern method in string Object. like this.
String test = new String("test");
test.intern();
so if you declare you username and password like this :
String username = new String("YOUR_PASSWORD");
it will not add to pool unless you call intern method.
so try the above way or use StringBuilder class. The garbage collection happens on your data.
Recently an interviewer asked me a very tricky question.
There are several parts of the question.
Why (question is why and not how) do you need to parcel objects while sending from one activity to another and not send directly
Answer I gave -
Parcelable gives the capability to developers to restrict object
creation which in a way makes it faster to use.
I was confused on the part, so decided to site difference between using serializable and parcelable :p (clever huuuhhh !),
http://www.developerphil.com/parcelable-vs-serializable/ used this reference.
While using Bundle, when we use String, int we do not need to parcel the data, so do you think the String/int is by default internally parcelled ?
Answer I gave -
because String/int is a primitive data-type, if we had used the
Wrapper class directly, might be possible we had to use parcelable(I
am not sure on that part)
I did not get any useful link after googling, also I or the interviewer is not quite satisfied with the answer.
If you guys can help, would be wonderful !
Why (question is why and not how) do you need to parcel objects while sending from one activity to another and not send directly
Parcelling/serializing objects isn't for speed as you had guessed.
When you're sending data between Activities, and especially between different applications (remember that Intent objects aren't only meant for communication between your own Activities, but are also for between yours and those of other apps as well), you cannot expect the sender and the receiver to have access to the same memory address spaces.
Android's documentation states that applications run in their own discrete memory spaces. Here's a quote to that effect from the docs:
Each process has its own virtual machine (VM), so an app's code runs in isolation from other apps.
So when you want to send an object myObject to some receiving Activity, you can't send its reference/pointer because the receiver won't necessarily have access to the location specified by the pointer. Instead you'll have to send some representation of myObject that the receiver can access and use -- this is why you need to marshall the data into a form that can be unmarshalled, and the easiest way to do so is to simply have the class of the object implement Serializable which lets Java do its best to convert the object into an array of bytes that can be easily sent to and unmarshalled by the receiver. But since Serializable uses reflection, this is slow.
You can use other ways that are faster to marshall the data -- one, for example, is converting the object into its JSON representation using a library like Gson and just sending it across since any JSON document can be represented as a String and easily converted back to a Java Object. Another way, which is probably faster in pretty much all cases is using the Parcelable interface which lets you specify exactly how you want to marshall the data and exactly how it should be unmarshalled. It basically gives you more control on the transmission of the object.
The tl:dr: Parcelling/Serializing etc is used because you can't send memory addresses across, so you have to send the actual data of the object and it has to be represented in some form.
While using Bundle, when we use String, int we do not need to parcel the data, so do you think the String/int is by default internally parcelled ?
How Bundle works internally is that it puts everything into a Map and parcels/unparcels the data as needed (ie when get/put is called). For putting Objects into a Bundle, the object's class needs to implement Serializable or Parcelable because it needs to tell the Bundle how it should be marshalled/unmarshalled internally.
But primitive types and Strings are simple enough and used often enough that the developer doesn't need to specify how that needs to happen and Bundle provides convenience methods for it. I can't give you a solid answer at the lowest level of how they works because a lot of the Parcel code is natively implemented and I couldn't find it online, but they must certainly be straightforward to convert to their representation in bytes.
Just to add what #uj- said, Parcelling/Serializing is needed as #uj- said it will be sent across JVMs so they need to be converted into some format so that the other party will be able to understand.
Let me take an example to explain why serializing/parcelling is needed,
you are sending data from an application written in "C++" to an application written in java, so the following are the classes,
In C++,
class Android {
public: int dataToSend; //for example purpose making field public and omitting setter/getters
}
In Java,
class Android{
public int dataToSend;
}
suppose the C++ code generates dynamic library (which will be generated by compiling using the standard C++ compiler and then linked), and Java code generates a jar (by compiling using the javac).
When the C++ application sends data (object of Android class) to the java application the way it is compiled and linked in C++ is completely different as compared to the way its compiled in java and hence java will be wondering what has this C++ application sent to me.
Hence to get rid of such problems serialisation/parcelling is needed which will make sure that both of the application know how the data is converting while transmitting through network (in case of android how it is transmitted to another activity, may be in same or different application).
And yea when we start comparing Serialisation and Parcelling, Parcelling gets the upper hand as we will be specifying the way the data must be converted when sending the data, else in the case of serialisation the object is converted to string using reflection and reflection always takes time. Hence Parcelling is faster compared to Serialisation.
For your second question,
if we consider the above example itself then we can say that String and int being primitive types (no user defined fields in them) and hence android will be able to handle the marshalling and unmarshalling of the data which will be sent.
I tried going through the code when we go on digging deeper we end up getting native code as said by #uj-.
Some extract from the android source code:
while writing the parcel:
parcel.writeInt(BUNDLE_MAGIC);
int startPos = parcel.dataPosition();
parcel.writeArrayMapInternal(mMap);
int endPos = parcel.dataPosition();
parcel.setDataPosition(lengthPos);
int length = endPos - startPos;
parcel.writeInt(length);
parcel.setDataPosition(endPos);
while reading the parcel,
int magic = parcel.readInt();
if (magic != BUNDLE_MAGIC) {
//noinspection ThrowableInstanceNeverThrown
throw new IllegalStateException("Bad magic number for Bundle: 0x"
+ Integer.toHexString(magic));
}
int offset = parcel.dataPosition();
parcel.setDataPosition(offset + length);
Parcel p = Parcel.obtain();
p.setDataPosition(0);
p.appendFrom(parcel, offset, length);
p.setDataPosition(0);
mParcelledData = p;
set the magic number which will identify the start of the parcel while writing and the same will be used while we read the parcel.
Hope I answered your question.
I would like to transmit an Android Object over a Socket with low overhead.
Should I use standard java.io.Serializable or android.os.Parcel?
Thank you!
Neither.
Parcel is designed for IPC, and other uses are albeit arguably efficient, dangerous. The documentation says
Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.
This also means that you need to be sure that the remote side has got the exact same version of Android and of your code to be sure it will work.
Serializable has similar problems, and in the (android) dcumentation there is even a hint towards the solution:
Warning: this interface limits how its implementing classes can change in the future. By implementing Serializable you expose your flexible in-memory implementation details as a rigid binary representation. Simple code changes--like renaming private fields--are not safe when the changed class is serializable.
[...]
Recommended Alternatives: JSON is concise, human-readable and efficient. Android includes both a streaming API and a tree API to read and write JSON. Use a binding library like GSON to read and write Java objects directly.
If you want to move data from one device to another, I think you are better off creating a protocol for the data, ship it over, and populate the remote objects with that data. JSON is probably a good place to start.
Good luck!
If your message is longer, more complex or otherwise you need more efficiency, I would recommend to try use Google Protocol Buffers. They would allow some reasonable amount of alterations like adding new fields, or removing previously optional fields, or adding a completely new structure as a field. However you will also have the real classes with the real setters and getters (can be immutable versions or mutable builders, how do you prefer). Stricter control over that do you put is not as bad thing as may appear.
think XML, but smaller, faster, and simpler
The major drawback of serialized objects is not that you cannot alter the protocol details later. Differently, you can do many compatible changes if you introduce versions numbers and you cannot rename the property name in JSON either if you want legacy client to find that property.
However serialized objects are Java specific and you cannot have a more efficient C++ server client or use Python for prototyping, for instance, if you decide in the future. Protocol buffers are language neutral.
Transmitting an object through a socket depends a lot on what will be receiving the object. Usually such a transfer relies on a text-based serialisation such as XML or JSON.
First, define an object to send. As an example, we can define a class called Message to encapsulate our communications:
public class Message implements Serializable {
private static final long serialVersionUID = 1L; // Your version number
private int senderID;
private String messageText;
public Message(int id, String text) {
senderID = id;
messageText = text;
}
public String getText() {
return messageText;
}
}
Next, instantiate the object, wrap the socket's streams in object streams, then send the message across the socket:
Message sayhey = new Message("123456789", "Hello");
Socket socket = new Socket(host, port);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(sayhey);
On the other side of the socket, the message can be retrieved and used by invoking methods on the returned object:
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Message messageObject = (Message) in.readObject();
String messageText = messageObject.getText();
you can implement Serializable.
I have a class, say A, in Java with few methods and some static variables.
I am building a WebView based application in Android. I have injected an instance of class A using addJavascriptInterface method. (The application is actually using Phonegap)
I have a Javascript function which performs RSA Encryption using public key K(n, e) passed to it.
encryptString(n, e);
The 'n' is returned by a method from class A, called like:
var keyn = window.A.load("publicKey");
This is where I have a problem. When I pass 'n' as string, and 'e' = "10001" as string too, the encryption works well. But, when I pass keyn recived from the method, it doesnt work.
encryptString("42342abcdefg2232", "10001"); // Works
encryptString(keyn, "10001"); // Doesn't work :(
I have logged keyn in logcat and it shows that value is recived correctly in the variable keyn.
What is the problem then?
PS: I have tried two different RSA encryption libraries and same problem with both. So, most probably it is not a problem in the encryption code I am using.
The solution I found was that I passed keyn as new String(keyn) and it worked. In the journey I found the differences between string literal and string object in Javascript. I suppose WebView basically returns an Object and we need to convert it to string object before passing it to the function.
Anyone who could elaborate it more is welcome.