nelenkov/android-keystore

Android M Preview 2

Opened this issue · 25 comments

Hi There,

Your work on the android keystore has been really helpful. I have noticed however that it doesn't work anymore with the latest Android M Preview. I am just wondering if you have any thoughts to look into this?

I have tried creating a new KeyStore class for M however I am having no such look with it.

Thanks! :)

The AIDL interface has changed, so if you want to talk directly to it, you need to pull up the latest AIDL from AOSP's master branch.

Thanks for the speedy reply Nick.

Could you provide a tiny but more direction? I'm well able to work on this myself just not sure where to start! Thank you!

Yes, that's the one you need. Not sure what you are trying to do, but M has supported, public APIs for symmetric key generation, so you don't really need to use the raw AIDL interface. See M API reference for details, (android.security package).

The real problem I am having with the new APIs is that I can't retrieve a byte array from the SecretKey that is returned when generating or retrieving a key. I need this byte array for encryption with another library.

Calling getEncoded() on the SecretKey simply returns null and trying to wrap it using Cipher throws an exception. Do you know of any way to get this byte array back?

I am also having terrible trouble trying to implement the AIDL interface. The KeyStore always reports itself as UNINITIALIZED. Many thanks for your help!

Well, this is kind of the point of the keystore, not giving you the raw keys :) There are major changes in how the keystore works in M, especially wrt to symmetric keys (see my blog post). I don't think you'll be able to get the raw bytes, but I haven't looked into the changes in preview 2 yet.

I understand! I'm going to look into my database solution to see if I can use Cipher to encrypt it. Thanks for your replies. Appreciate it!

It looks like the source code in this project could use a refresh. Currently looking into this (many IKeystoreService method calls fail now on M preview, as originally posted here). My SDK is giving me headaches, and I have to resort to reflection in order to call the new methods, despite having the new targetSdkVersion set to M.

Hi @elouet,

I would gladly help in anyway I can!
I'm curious. have you got this to work on M?

Thanks,
Gavin

Not yet, I need to spend more time on this, and possibly first off migrate the project to gradle so that it builds with Android Studio.

As I said, Android M has official APIs for generating symmetric keys inside the keystore, so the hacks employed by this project are not really needed anymore.

If you do add gradle support, please preserve the current project structure (i.e., don't move files directories around).

This is a good point. I have been using this code for other purposes, mostly in a context where the app has the system UID and can set the keystore state (initialize and unlock it). I need my code to work on M. I just moved back eclipse again, and it seems to work fine. I shall focus on the M-specific changes first. I don't like the whole gradle thing so much either.

I've started making progress on coping with the new API here : https://github.com/elouet/android-keystore/tree/android_m_update
AES encrypt/decrypt seems to work on legacy devices as well as my Nexus 5 running the latest M preview images (I believe this is preview #3).

I still find this library very useful, since it allows direct access to the keystore without being married to specific crypto primitives, and allows explicitly checking the difference between locked/unlocked/uninitialized.

daen commented

Hi Nelenkov, thanks for your android-keystore library.
It's very useful.
Since Android M is published now, and I found the android-keystore library is not work on Android M any more.
Looks like the "IKeystoreService.aidl" is changed.
Is there any update for android-keystore library?

Amoi commented

hi @GavinThePacMan ,

i've walked into the same situation: try to use the AndroidKeyStore to protect our keys, but can not retrieve the raw key data after we put the key into it. do you have any update for this?

Amoi commented

hi @nelenkov ,

so do you think for the case like that, we need to protect the keys our self?

@Amoi, that's by design - the Android keystore won't let you have the key.

I know this is an old issue, but mostly for people who have this question in the future, I have had to solve the keystore/encryption problem on Marshmallow, too, so an example of how to do this sort of thing on 6.0+ is in this library. It's a pretty specific use case I've had to fulfill, but you can look through the code to see how to do the same sorts of things (namely AES encryption) with the newer versions of Android and the keystore.

@nelenkov, thanks for putting this together - I've used a good bit of your code in my library, and it saved me an incredible amount of time and strife.

@kevjava Looks good. However, note that this is a sample project, so it's missing a few things, namely ciphertext authentication (HMAC). CBC mode allows bit flipping without knowing the key, so if you intend to use for production, you might want to add HMAC. You would need to generate a separate key for HMAC, Marshmallow keystore supports HMAC keys as well.

That is a very good point, @nelenkov - thank you for the pointer. I've added it as an issue, and I'll look into implementing that shortly. Down the rabbit hole we go :-)...

Amoi commented

Thanks @kevjava , the reason I want to retrieve the raw key is I want to use our own ssl lib and also take advantage of the system key store mechanism(To protected the key). The library you mentioned is great ,but I take a quick look, it seems you do not need to retrieve the raw data of the key, right?

@Amoi - You're right, I don't need to retrieve the raw data of the key for my purposes. If you needed to, I imagine you could use the spongycastle library to generate the key manually and store it securely elsewhere. The Android Keystore won't give it back to you once you do store it, though.

Amoi commented

@kevjava Thanks. The solution we came up is use two keys - One stored in Android KeyStore and used to decrypt the second key, the second key I could use to encrypt our data with the specific lib. Anyway, Android KeyStore wins . :-)

@Amoi - Just keep in mind that you could lose that key if/when the user uninstalls the application or changes the security method on the device. I've noticed Pre-Marshmallow weirdness in this regard, and different devices behave differently. Of course, there is relatively little definitive documentation from Google.

Amoi commented

@kevjava - Useful article! in fact, for Pre-M, we use a local keystore(basically a file) to store the key and for After-M we use the AndroidKeyStore