Office Hours — Today, August 13

Saturday, August 10

Mark M.
has entered the room
Mark M.
turned on guest access
Aug 13
9:00 AM
Urban
has entered the room
Urban
Hey Mark!
Mark M.
hello, Urban!
how can I help you today?
Urban
Thank you for taking time to be here today
I have a few (aka a lot) of random quetions that I got from re-reading your book
Mark M.
I will try to give you random answers! :-)
Urban
So if you have time I would kindly ask you to answer them.
Thank you
Let's beggin :)
First question is (probably too much) basic. I have been using AsyncTasks here and there but always in activities and never in fragments. However, due to config changes, ATask needs to be restarted every time, probably making this not the best practice. Therefore, my question is if putting ATasks always in F with setRetainInstance(true) is a better aproach for handling such scenarios?
Mark M.
AsyncTask itself is an old approach -- most modern Android app development will use other things (LiveData, RxJava, Kotlin coroutines, etc.)
if you need to use AsyncTask, then I definitely recommend using a retained fragment, as you suggest
9:05 AM
Urban
So, what would you reccomend using instead of ATasks? LD is a rather broad term itself
Mark M.
if you are using Kotlin, coroutines work nicely
(perhaps coupled with LiveData)
Urban
I am not using it (yet) but will do so in the meantime. So will definetely check this out and consider the replacement. Thank you for answering original question aswell :)
Second quetion is somewhat related to this one
Second question is about LiveData and JavaRx. I have learned both principles but I found it difficult to recognise when each should be more extensively used. I use LD solely for linking them with ViewModels and populating content with them. On the other hand, I find linking (simple) methods easier with "normal" Java compared to reactive programming. Therefore, I would like to ask when (in which scenarios) would you reccomend using LD and JavaRX?
Mark M.
by JavaRX, do you mean RxJava?
Urban
Yes, I am sorry for mistake
Mark M.
no problem -- I just was uncertain if you were referring to something else
Urban
It's pretty basic question but I know that these principles are a future of modern programming and should probably start utilising them as much as possible
Mark M.
personally, I tend to use LiveData just for the "last mile" portion: exposing data updates from a ViewModel to the activity/fragment using it
RxJava is what I would use for having data sources and repositories supply data to the ViewModel... if you are working in Java
9:10 AM
Mark M.
(if you are working in Kotlin, coroutines would fill that role)
however, RxJava has a steep learning curve
a developer that has no experience with RxJava might elect to use something else, rather than try learning RxJava
Urban
I have some experience with it (on the contrast to coroutines) but didnt really use it much as I did not feel I need to
I would rather use other principles (such as ATasks and threads) to obtaine the data and later process them
Which is probably not the best alternative nowadays
Mark M.
there is no problem for which RxJava is the only solution -- it is merely an option for thread management
in a Java app, without RxJava, I would tend to use plain threads or threads wrapped in LiveData, as I demonstrate in *Elements of Android Jetpack*
Urban
This is what I would normally do, but wouldnt you say that using RxJava instead of this procedure for all Threading operations is better?
Considering I would like to "optimise" the code as much as possible
Mark M.
RxJava is a better solution for larger apps, where the investment in learning RxJava can be worthwhile
for small apps and developers who have not learned RxJava, it may not be worth it
9:15 AM
Urban
Okay, I see
So basically you're saying that both principles are fine
And while RxJava might be a little bit better, I am fine using standard procedures?
Mark M.
if your app works properly, and the people who will be maintaining the app understand how it works (today and tomorrow), by definition it is "fine" :-)
Urban
Okay, so that being said I will try to use RxJava as much as possible while not thinking too much about it then
One final thing about this: are the same things that you have said about RxJava true for coroutines in Kotlin?
Mark M.
I think that coroutines are easier to learn than is RxJava
Urban
View paste
So, lets assuming I know Kotlin, you would then suggest me to use these in all threading operations (if possible)?
(Dunno why I just pastedd above)
Mark M.
this chat site sometimes behaves a bit strangely -- don't worry about it
as I said earlier, in Kotlin, I use coroutines in addition to LiveData
you will see this in *Elements of Android Jetpack* and *Exploring Android*
so, the ViewModel uses coroutines to work with repositories and data sources, and the ViewModel exposes LiveData to the activity/fragment
9:20 AM
Mark M.
here, the LiveData is not for threading, but for lifecycle-aware update delivery
Urban
So basically you use them for all threading operations right?
Mark M.
"all" is a strong word :-)
I use coroutines over creating my own threads
however, libraries might do their own thing
Urban
Okay, thank you very much for your extensive reply on this topic
I definetely need time to learn Kotlin, especially after talking with you
Next question is more about app's secutiy (I know, rather broad topic)
With this in mind, I was considering (in edition to DB encription) implementing security agains rooted users and against MITM attacks with SSL (probably using my own certificate). Would you agree with me on these or would you also suggest some other technique for defending the app aswell?
Mark M.
when it comes to app security, you first need to decide what you are defending, and what you are defending it against
so, for example, an encrypted database can be useful if you are defending the user's data against somebody who might steal that user's phone
however, an encrypted database is not useful in some sort of DRM system, where you are trying to defend what you think is "your" data against the user
SSL certificate pinning of some form can be useful as well, assuming that there is enough sensitive data being passed over the Internet connection to make it worthwhile
9:25 AM
Urban
reagarding the SSL: is it even needed if I send data between a server that I own (aka buy somewhere for hosting) or is self-signed certificate enough?
Mark M.
well, I would recommend Let's Encrypt over a self-signed certificate, as it is just as easy and results in less client-side headache
Urban
with "Let's Encypt" you mean end-to-end encryption as a standard procedure or a special type of encryption=
Mark M.
no, I mean the Let's Encrypt free SSL certificate service
Urban
oooh okay, I see
sorry for dumb question
will take a look at it definetely then
Mark M.
I should not have assumed that you recognized the name, sorry
Urban
So they generate certificates that I can later connect both server and app side with?
Mark M.
yes, just like a commercial SSL certificate authority (Verisign, Thawte, etc.)
and the Let's Encrypt certificates are recognized by Web browsers, whereas a self-signed certificate is not
even if you are not currently planning on having a Web site or Web app on that server, you might want that in the future
9:30 AM
Urban
okay, I see. Will definetely look into this one then
So, that being said, what general security techniques would YOU put in your app if you were to publish it?
You dont need to be specific, just in general
Mark M.
again, it depends on the app, the user, and the "threat vectors" (i.e., who the attackers are)
for a simple app with ordinary users, ordinary data, and just random hackers, using internal storage for on-device data and SSL for network communications are the only cryptography things I would worry about
the more "at risk" the users are, or the more secure the data needs to be, the more likely it is that I would start looking into database encryption, SSL certificate pinning, etc.
Urban
I see. I was also thinking to implement protection against rooted users. Would you think this is sensible to do?
Mark M.
no, because rooted users are your users
or, rather, there are two types of people who would use your app and root their device: regular users and attackers
Urban
So, you're saying that I would just deprive those users of my app without much safety gain?
Mark M.
I am saying that defending against root users is impractical, and there are not that many of them that would be trying to attack your infrastructure
9:35 AM
Mark M.
Tim O'Reilly famously said "your problem isn't piracy; it's obscurity"
Urban
I see. Also, do you think it's sensible to encrpt chat internal storage (SQLCipher) considering you're only risk is if someone's phone got stolen and hacked?
Mark M.
again, it depends on the data
cached weather forecasts? no
passwords for an on-device password manager? yes
Urban
I was thinking chats with other users for example
Which is somehwre in between I guess
Mark M.
agreed
for example, if the chat app might be used by at-risk people (such as the current Hong Kong protestors), on-device encryption can be useful
Urban
Would you personally encypt it?
Mark M.
personally, I would use an encrypted database in that situation... but I am fairly comfortable with encrypted databases
after all, I maintain CWAC-SafeRoom and have contributed a variant of its code to SQLCipher for Android itself
Urban
So you have SQLCipher in mind, correct?
Mark M.
yes
AFAIK SQLCipher has gone through more security audits than anything alternative that I know of that is available for Android
(er, "than any alternative", sorry)
9:40 AM
Urban
Is the encryption and decyption process of it rather short or it requires extensive CPU?
Mark M.
it is definitely slower than plain SQLite access
usually, though, that shows up when your database is not well-optimized
so, for example, if you execute a SQL query that needs to do a "table scan" and read in every row, that is slow normally and *really* slow with SQLCipher, due to the decryption overhead
however, if you can put an index on the table that allows SQLite to only read in a small subset of rows, then everything is faster
Urban
Did you have in mind any other sort of optimisation or just indexes in this case*
Mark M.
that's the big one -- basically, avoid "table scan" queries
you want SQLite to read in as few pages as possible, as each page needs to be decrypted when using SQLCipher
in-memory caching can also help, so you do not re-query the database unnecessarily
Urban
thank you for this extensive answer
View paste
one last question regarding SQLCipher: I was thinking where the key should be stored and thought of storing it in Android Keystore. Would this be a valid or would you opt for other place to store it?
9:45 AM
Mark M.
if by "storing it in Android Keystore", you mean "storing it in a file encrypted via the AndroidKeyStore", then that can be OK, at least on Android 5.0+
sometime, I need to reconfirm whether the AndroidKeyStore is stable if the user changes their PIN/password
Urban
Can we not store this key direclty in the AKS itself?
Mark M.
I don't think there is an option for that, though I may have missed something
Urban
So, would you use file encrypted by AKS to store the key in or would you rather store it elsewhere?
Mark M.
I have used AKS to encrypt a file that contained a generated key, where that generated key is what I used in SQLCipher for Android
this is for cases where you feel that the device authentication is sufficient
or you have other factors that you are going to use (e.g., combine the generated key with a user-entered passphrase)
Urban
With "device authentication" you mean that you assume that the user using the app is the phone's rightful owner?
Mark M.
yes, and that they were able to enter the PIN/password/whatever to get past the lockscreen
9:50 AM
Mark M.
so, if the user's PIN is 1234, that means that your database security is not very good
Urban
I see. So basically there is no point enrypting the storage if the "hacker" can you lock your screen easy anyway
As the time is running low, I will just ask you one more thing
We have discussed encryption of internal storage where you are the only one that has unique key
On the other hand, assuming you want to encypt the online DB with a key that you DO NOT want to store in the base itself, what would be the best procedure to do so?
Mark M.
what do you mean by "the online DB"?
Urban
So every user has to have access to it but not hardcode it anywhere
MySQL DB for example
From which you want to retrive data
Mark M.
well, the encryption key for the MySQL database would be in your Web service
an Android app is (hopefully) not going to be talking to the MySQL database directly
9:55 AM
Urban
So you would encrypt the storage in the service level? However, there are two issues I see with it: you still need to save the key and secondly, this procedure does not provide end-to-end encryption
Mark M.
"end-to-end encryption" usually refers to two clients, not a client and a server
so, in your chat case, chat messages are encrypted in a way that each participant can decrypt, but the server cannot
so, you would not need MySQL encryption in that case, as the data is pre-encrypted by the time it gets to your server
key exchange for end-to-end encryption is a BIG challenge
rolling your own end-to-end encryption is likely to give bad results
Urban
So basically, you suggest that easier (and also viable aproach) would be just to have a secure connection with the server (via SSL) and encrypt the data in the database server correct?
bad results in what way?
Mark M.
security flaws
I mean, this is the sort of thing that Signal, WhatsApp, etc. struggle to do, and they have teams with deep cryptography experience
and deep experience in end-to-end messaging in general, at scale
10:00 AM
Urban
So, what approach of data encryption would you suggest? Have a secure connection with the server (via SSL) and encrypt the data in the database server?
Okay, so end-to-end is probably not the best alternative for me then
Mark M.
end-to-end encryption might be an ideal solution, but it is difficult to get right
if I wanted to do it, I would be looking to see what the current status is of implementations of Signal's Axolotl (Double Ratchet) protocol
Urban
So you would try to implement this protocol in your app?
Mark M.
but, all of that is rather outside the scope of what I can support in this chat
right now, it is "the gold standard" for end-to-end encryption
Urban
What do you mean "out of scope"? Too difficult or to CPU intensive?
Mark M.
too unrelated to Android app development, which is what these office hours are about
I help developers with Android app development questions -- I do not claim to be sufficiently qualified to provide advice on server implementations, etc.
Urban
I see. So final thing: you would try to implement this protocol to your database communications or would you do server encryption?
Thank you for your honesty on this part
Mark M.
I do not really understand that question sorry
and, the chat was scheduled to end ~5 minutes ago
Urban
I see. Thank you very much for your help
10:05 AM
Urban
It has been a fun time
Mark M.
you're welcome!
Urban
I will probably come back in the future with more random questins
Mark M.
the next chat is Friday at 4pm US Eastern
Urban
until then, thank you for making this possible
Mark M.
the transcript for this chat will be uploaded to https://commonsware.com/office-hours/ shortly
Urban
and have a gd time
good*
till next time :)
Mark M.
you're welcome, and thanks for subscribing!
have a pleasant day!
Urban
has left the room
Mark M.
turned off guest access

Saturday, August 10

 

Office Hours

People in this transcript

  • Mark Murphy
  • Urban