I'm trying to install client certificate on android programmatically, using the following code :
Intent clientCertInstall = KeyChain.createInstallIntent();
clientCertInstall.putExtra(KeyChain.EXTRA_PKCS12, clientCert);
clientCertInstall.putExtra(KeyChain.EXTRA_NAME, "Client Cert");
MyActivity.this.startActivityForResult(clientCertInstall, REGISTER_CLIENT_CERT);
When the installation activity launches, android requests the user to enter password for the certificate (although there is no password and just clicking ok works)
More over, after clicking OK the user is requested by android to enter a name for the certificate, although i gave him a name in the "KeyChain.EXTRA_NAME" parameter.
This behavior annoys my users, they don't understand about certificates and just want it to be installed automatically without dialogs, how can i achieve this ? avoiding even one dialog would be very helpful.
Thanks,
This is "by design". Allowing apps to install certificates without user approval would open up the possibility of man-in-the-middle attacks on SSL-secured communication channels, such as online banking. That said, the dialog tells you none of this and users would undoubtably press OK regardless of what it said.
Related
I am trying to gain access to an API from an Android application, so I can extract the GET request and use it on my PC instead. I have verified that this is indeed possible, however, I have one problem: Their Firebase integration gives me a 403.
The app works like this:
Open app
Enter your address and select it from a list
Press "Add address"
App sends a POST request to Firebase (probably registrering a session or something)
App succeeds and returns to a "view" page, that contains the info I want to extract
I've extracted the app using adb pull /data/app/....apk and then used AddSecurityExceptionAndroid to enable debugging via Charles Proxy and so on, from my computer. Once I've built a new APK, simply install it with adb install application.apk.
Once I launch the newly installed app, I am once again greeted with the same "Enter your address" popup, like it completely forgot I already entered it once. Is there a way to bypass this, so the APK I extract already has this data? Or keep it on the device for future use, so when I install my patched APK, it's already "signed in"?
The problem is, if I only enable SSL proxying for *.apiwebsite.com and let my phone handle everything else, it works great until I need to send a POST request to firebaseinstallations.googleapis.com, where my phone just hangs and eventually the app crashes. It happens right after I press the Add address button, after searching for my address and selecting the correct one.
So I either need to find a way to make it not fail with Firebase, or somehow extract the APK, so I can "sign in" beforehand, pull the APK, patch the APK, and then install the APK, so the app already knows I am "signed in".
The Firebase error is:
Requests from this Android client application correct.url.here are blocked
Okay, I managed to get something working. First I installed Genymotion, then I booted up a rooted Android 8.0 virtual machine, to which I then installed the app I needed to "debug" and HttpCanary.
Logged every TLS/SSL request perfectly and I was able to retrieve the URL for the API I needed.
I added Firebase integration to my Android app and unexpectedly ended up also getting Google Smart Lock password management behavior for free.
Although I am reasonably happy with the behaviour, I'd like to modify it ever so slightly.
The unexpected behaviour: I have a login dialog that's used to provide credentials to SMB shares. Now that I have integrated Firebase, I end up with the following unexpected addtion to my login dialog box:
What I'd like to modify: I'd like to constrain the login credentials to the target device (i.e. do not share userid/passwords across different SMB target devices), in the same way that Chrome does not reuse credentials across different web sites. (I think accidentally sending cached credentials to a machine they don't belong to constitutes a mild security risk). For the given example, I'd like Google Smart Lock to prompt ONLY for credentials for \lothlorien.
Entered credentials show up in my Smart Lock credential cache in my browser as being associated with my Android application.
Oddly, I didn't do anything explicitly to make this behavior appear, other than (1) add firebase integration, and (2) name the EditTexts in my activity. It's an Activity, not a dialog box, although it does use Material dialog themes.
If there were some easy way to associate them with credentials for "smb://lothlorien" (for example), I'd go for that.
Given that I already have functionality to cache and store credentials, and given the non-trivial nature of the Google Smart Lock apis, I'd be just as happy to disable the Smart Lock prompt altogether.
Either fix would work for me. Associate credentials with a specific machine; or disable the feature in the dialog box.
My use case is, My app should verify the device pin/password is set. if not then enforce the user to set it up. This has to be performed every time user launches my application and proceed after verification of the pin/password. Can some please help how to implement this. I am using apache cordova and jquery for my application development.
This would be plausible if there were, say, a manifest permission you could add since Android checks the permissions before installing the app, but there isn't that option... Personally, I wouldn't enter my phones "master password" into an app. Too sketchy. Your best option is to create your own password system handled by your app. So whenever the app is run (or whatever your specific need is) you can ask the user to input his password.
I am planning to drop my app in Google Play(earlier Android Market) because of push notifications (whenever a new version) , security for apk and so on.And also since apk is secured with Google play(paid apks) i dropped of downloading the apk from my website (only authenticated people can download the apk)
Actually its a business app for particular users with username and login access. Everything was fine in the App with login and security mechanisms
I am thinking of a way to restrict the other users who are not from the list while installing itself.
My question is whether any kind of filter or authentication mechanism can we set while downloading the application from the Google play it should ask for a password or something like this to filter the unauthorized users to download the app..
My ultimate aim is i don't want the peoples to try it after downloading unnecessarily
Can anybody help who have tried all those in android market
Ok.. One thing after another..
Google propose their licensing mechanism. However app would need internet connection, which is disadvantage if otherwise it doesn't need it. If I got it right your does need to connect to server so this is not a problem for u.. It seems to me you are already familiar with this method.
Mechanism for password protecting downloading or visibility of apps on Google Play doesn't exist today..
You can identify users with IMEI (in case you don't consider using app on tablets, which doesn't have it), WLAN MAC, BT MAC address or some exotic combination of these methods, and you use this as authentication.
The best solution, from my point of view, is to allow people on market to download it. Your application is already using some mechanism of authentication (user/password) to server. So if 1st thing user need to do is login, and any functionality is disabled if that doesn't pass. If it pass, you already know who is your user and what privileges he has.
The thing is here that I am not so sure what are your concerns when user without login/pass download application if everything after that screen is disabled before authentication. User will download (if they find it..), they will install, try to use it, see that's not possible without credentials and uninstall it.
Hope it helped.. I will try to add few more links in a while..
My objective:
Create an EAP WiFi configuration - including the CA Certificate - in Android programmitcally.
Problem:
How do I install a CA Certificate programmatically (and then reference that certificate in the EAP WiFi configuration)?
I found a very useful link already that allows me to create and save EAP WiFi configurations here:
How to programmatically create and read WEP/EAP WiFi configurations in Android?
However this assumes that you have already installed the CA Certificate on the device. I would like to install the certificate within my app - either from the resources in the app, or sent from a server.
Is this even possible? (Rooting is not an option in this case.)
If so, how?
Additional info...
I also found a way to add a certificate to a KeyStore:
https://stackoverflow.com/a/4490543/1172101
However this is used specifically for creating a secure socket and connecting via HTTPS. I want to use the certificate for WiFi.
Unfortunately, I have yet to find a way to install a CA Certificate programmatically - from within the app.
However, it is possible to install a certificate via the Web browser in Android. Thus, the solution (for now) is to:
Launch an intent to open a URL in the Web browser that goes directly to the CA certificate.
This works but there are some challenges:
The user must name the certificate. This is a challenge because we are adding the WiFi configuration programmitically. Thus we have to ask the user to give the certificate the same name.
The user must enter a password. If they don't have a password set up, the user will create one and enter it twice. If they have set a security password, the user will have to remember that same password and enter it.
Assuming the user successfully completes these steps, he is left hanging in the browser.
This leads to a few questions:
From my app, is there a way to force a name for the certificate that the user installs via the browser?
From my app, is there any way to know when the certificate installation has completed and then give focus back to my app?
Just let me know if you need any clarification.
You cannot install it directly since non-system applications don't have access to the key store. On ICS, there is an API for this KeyChain.createInstallIntent() that would launch a system dialog asking the user whether they want to install the certificate. On pre-ICS you can achieve the same thing by launching the install intent using the component name directly (this may or may not work on all devices though). Going through the browser is actually a roundabout way of doing the same thing.
As for your questions:
you cannot specify/force a name. Why do you care about the actual name?
Not really through the browser. If you use the system intent, you can return to your activity and will get a callback if you use startActivityForResult().
Update: Android 4.3 has WifiEnterpriseConfig which both creates a profile and installs keys and certificates in the system credential store. You only need the CHANGE_WIFI_STATE permission.
I am currently looking to solve the same issues. The best thing that I have found is KeyChain.choosePrivateKeyAlias() allowing the user to select which certificate to use for the SSL. From there you can retrieve the Alias name and pass it to the enterprise wifi configuration.
I'm looking for the same... as for your question, #Nikolay:
you cannot specify/force a name. Why do you care about the actual name?
The EAP profile needs the name of the already-installed-CA. If you look at the example in part 4, you can specify:
final String ENTERPRISE_CA_CERT = "";
In the example, the profile does not use the CA name, but that could be the case for other EAP profiles.