Developing a simple android application that will cast a URL (webpage) on bigger display.
For publishing "the receiver app must be served over SSL (HTTPS)". For that I have generated self-signed SSL Certificate and plan to use the same.
URL for publish
However, On trying to access the page from browser, it gives following warning:
The site's security certificate is not trusted! You attempted to reach
basilapps.com, but the server presented a certificate issued by an
entity that is not trusted by your computer's operating system. This
may mean that the server has generated its own security credentials,
which Chrome cannot rely on for identity information, or an attacker
may be trying to intercept your communications.
So my query is:
(A) Will self-signed certificate will work fine during publishing?
(B) If not, then do I need to purchase SSL certificate from trusted authority?
(C) Are there freely available trusted certificates services available?
Thanks
Self-signed certs do not work and yes, you need to get/use a trusted one form a known authority. If you can use App Engine, that works since it already has that. For development, either use http or use App Engine or even Google Drive (the last two support https).
Related
My app needs to consume webservice, and I would like to authenticate app against server with certificate.
However, embedding keystore with signed key into package is considered bad practice (and explicitly warned against: https://developer.android.com/google/play/asi) as it can be extracted an decrypted.
I can generate private key with android provided keystore, and use it - but I still need it to be signed in order to verify it on server side.
In ideal case there shall be certificate chain, with trusted root authority and containing metadata of signed app package I could verify on server side.
Or is it somehow possible to use package signature in certificate generation process to prove that self signed certificate originated form untampered package?
A bad actor ("Trudy") can flash any custom Android ROM, including a ROM that removes package certificate validation during APK installation. Thus, any query that your app makes to its Android host OS is essentially a request to Trudy.
So, it might be possible to uncover the installation of a hacked APK with an unadulterated OS. But with an adulterated OS, all bets are off.
I think any solution for the client to self-validate would necessitate an authoritative validation of the host OS. Not easy.
Is it somehow possible to use package signature in certificate
generation process to prove that self signed certificate originated
form untampered package?
(1) Do you mean that each client generates a different self-signed certificate after installation and somehow cross-references this against the apk package signature in order to authenticate? Then no, this will not stop Trudy. (And it would not be useful in authentication, either.)
(2) Do you mean that the client has a universal private key embedded in the APK and that metadata on the package certificate can be used to verify against the private key? I do not know offhand if there are any available fields in the package certificate metadata in which to add this information. This is an interesting approach that you suggest. However, since Trudy might be the OS, theoretically Trudy could mock any result it wishes. I do not see this stopping Trudy.
This (SO) post by a developer for Proguard offers 5 options for handling secrets in your Android app. He notes:
Intrinsically, nothing on the client-side is unbreakable, but you can
certainly raise the bar.
I understand that you want user authentication of Webservice (API) using user's private key, and signed token would be verified at the server with user's certificate or public key already registered there at the time of user registration.
Are you looking to use external USB Token to store private key securely or you want to store the private key to be stored in Android device memory?
We have worked on such requirements on desktop (sample at https://web.signer.digital/Home) but not on Android. I know we can connect USB Cryptographic Token (like ePass2003 or others) to Android device with OTG USB and drivers for Android for some devices are available to access from Android but didn't worked on it actually. But this can be direction for you to look into.
A mobile application is public app, because an end user could possibly view and modify the app code. So, your application can't keep secrets from malicious users. That includes client certificates, which are required for mutual TLS (mTLS).
It is not safe to store any client certificate on the Android device for machine to machine (don't mix machine to machine with user to machine) mTLS authentication. It can be exported and then used on other devices by any user.
Operation systems (Android as well, some browsers, e.g. Firefox may have own) provides certificate storage, where CA certificates are stored and where client certificates can be stored.
It is a good idea to store user (issued for the user, not for the app/machine) client certificates there. Then mobile app should get an option to select which user client certs should be used for mTLS. But I want to authenticate my application without any user interaction. won't be possible. There must be at least initial user interaction: user client cert import to client storage, mTLS app configuration. That's IMHO the best and secure mTLS implementation. Real world example: Rocket Chat app.
You are asking for reverse TLS based verification ? Usually, clients verify web services because client's host OS trusts a particular CA certificate that is also used to generate the web-service TLS certificates.
The difference is:
web servers are protected and controlled by authors. Client devices are not. So, having a private key in app to sign the data sent to server is futile.
Still, You can explore Google's Licensing implementation with server side verification to enforce that a legitimately installed and licensed app can contact the server.
I am working on an application in which i have to post certain data via HTTPS services. I am using a self signed certificate but i am not sure where to register this certificate in my device and i don't want to use inbuilt browser kit. As i understand if i use browser kit i can add my certificate and install under "user" certificate.
Is there any way to add this certificate at "system" level in android rather than at "user" level ?
Can someone suggest one who has worked on VPN would be more aware on it....
I am working on an application in which i have to post certain data via HTTPS services. I am using a self signed certificate
If you are using HttpURLConnection, OkHttp, or HttpClient, you can create an SSLContext that uses a TrustManager that supports your self-signed certificate. I have some support for this with my TrustManagerBuilder in my CWAC-Security library, and there are plenty of examples of how to do this yourself, such as this blog post, by searching for android sslcontext self-signed in your favorite search engine.
If you are using some library for HTTP access, find out where you can configure its SSL functionality, or contact the author of that library if there does not seem to be an option for this.
Is there any way to add this certificate at "system" level in android rather than at "user" level ?
Users can install certificates. I am not aware that apps can install certificates, though I cannot rule it out. However, unless this certificate is needed for other apps, not just yours, please just use the certificate from your own app.
I have a mobile app which accesses web services at https://myserver.com/mywebservice.
If I create a self signed certificate and I put it on my server, when the mobile app accesses the web service it sees the certificate but it doesn't recognize it as it is self signed. But in this case if I have a "man in the middle" attack, the attacker can create it's own certificate, so the app sees the certificate and again it doesn't recognize it.
Question: When you use a certificate like those from goDaddy, is iOS or Android programmed to trust goDaddy certificates in order to work, so the fake certificate that the attacker uses is considered invalid? So if I make the app trust my certificate, I can use my self signed certificate the same way?
Also How can I know which certificates are trusted by iOS or Android?
Generally your app or the OS needs to trust the CA that issued the server certificate for this to work. If it is issued by a CA whose certificate is pre-installed, things just work. If not, you need to either install the CA in the OS trust store or modify your app to to trust it. It doesn't really matter who created the certificate, VeriSign or goDaddy certs are no more 'special' than your self-signed ones.
As for getting a list of trusted certs, Android 4.x and later lists those in Settings->Security->Trusted Credentials. For earlier version you have to write some code to enumerate them. Don't know about iOS.
We have a web service that should only be called by a specific Android app. What solutions are there for this problem?
The requirement is to not use authentication at all.
If it's only your client and your server, you can (and should) use SSL without purchasing anything. You control the server and the client, so each should only trust one certificate, the one belonging to the other and you don't need CAs for this purpose.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use the keytool included with the Android SDK for this purpose. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android, both server and client side. There is also a complete walk-through in my book, Application Security for the Android Platform, published by O'Reilly.
You'll normally store that certificate/private-key in a keystore of sometype (a KeyStore if you're using Android) and that keystore will be encrypted. That encryption is based on a password, so you'll either need to (1) store that password in your client somewhere, or (2) ask the user for the password when they start your client app. What you need to do depends on your usecase. If (2) is acceptable, then you've protected your credential against reverse engineering since it will be encrypted and the password will not be stored anywhere (but the user will need to type it in everytime). If you do (1), then someone will be able to reverse engineer your client, get the password, get the keystore, decrypt the private key and certificate, and create another client that will be able to connect to the server.
There is nothing you can do to prevent this; you can make reverse engineering your code harder (by obfuscation, etc) but you cannot make it impossible. You need to determine what the risk you are trying to mitigate with these approaches is and how much work is worth doing to mitigate it.
I guess this will work with proper authentification in place. First post I just stumpled upon was this one:
Securing communication from android to a web service
Hope it helps =)
If you're absolutely certain this web service will only need to be accessed by authorized applications/devices, go with client-side SSL certificates and restrict access at the server to only clients with authorized certs. This has the bonus feature of forcing SSL at all times so you don't like auth secrets over an open channel. Here's a quick guide for Apache, but you could use nginx too:
http://it.toolbox.com/blogs/securitymonkey/howto-securing-a-website-with-client-ssl-certificates-11500
I have a website with a number of RESTful web services that are used by an Android app. I want to let all requests go through HTTPS. Hence, I need an SSL certificate for my website.
Q: Do I need to buy an SSL certificate or can I use a self-signed certificate in this case? (I don't want to waste money on something I don't need.)
I can think of these approaches:
Buy an SSL certificate with Extended Validation (green address
bar). Probably not necessary.
Buy an SSL certificate without Extended Validation. This should suffice, no?
Self-sign an SSL certificate. Not sure what this implies?
If your biggest concern is not spending money http://www.startssl.com/ provides free basic SSL certificates for a year so that may be worth looking into. I do not know off-hand which CAs are trusted by default in Android so it may turn out to be effectively the same as a self-signed certificate from the app's perspective.
Using a self-signed certificate would require finding a way to make sure the Android app expected that self-signed certificate and trusted not only your initial certificate but any replacement certificates in the future. I suspect this is more trouble than it is worth although I do not know much about Android development or the app in question so I may be overestimating the difficulty involved.
An EV certificate does provide a stronger guarantee to the client that the service is actually your service and owned by you but it does incur additional costs. Choosing an EV versus DV certificate becomes more of a risk/reward judgement call. Annecdotally, I typically only see EV certificates on financial sites and others where you would typically expect to find a high bar for security.