Ensuring an iOS 4 app only runs if device meets certain password criteria - security

Our (internally distributed) iOS app relies on iOS 4.2's encryption to secure sensitive data.
However, that only works satisfactory if the user is using a good system-wide password.
I understand that this can be enforced by installing a configuration profile on those iOS devices by configuring the rules for a password.
Since the installation of this profile is optional to our users, how can we make sure our app only works if a certain profile is installed, or alternatively, if certain password regulations are met?
(We are not concerned with jailbreaks and related cracks to our software, so the ability to test for a config profile or other criteria inside our own code would be sufficient.)

What you can do, is create a (self-signed) SSL Certificate and add your signing authority to the configuration profile. Then, from within your app you can attempt to verify the certificate. The verification will only work if you trust the signing authority, which only happens if you have configuration profile has been installed.
You can read more about the process here if you wish:
http://blog.slaunchaman.com/2011/12/01/enforcing-ios-security-settings-in-third-party-applications/
Note: This may not be acceptable for submission to the App Store.

Related

Difference between client certificates and certificate pinning, Do I need both?

I have a .net WEB API publicly exposed and also a Xamarin Forms App which uses the API, the app needs to be extremely secure due to the data it manages.
I will create an HTTP Certificate for the WEB API.
The Xamarin Forms app will have a login/password to validate against a local Active Directory. via a /token endpoint, and using an Authorize attribute on all endpoints to assure that every HTTP call has the bearer token in it, I implemented that using this:
I based my implementation on this one:
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
Additionally the customer has asked us for Client Certificate Authentication, I dont understand how this totally works.
1. I need to add a certificate to the Xamarin Project, right? How do I Add it? How do I generate it?
2. In the Web API I need to validate each http call has the certificate attached.
I found this but not sure if it will work:
http://www.razibinrais.com/secure-web-api-with-client-certificate/
However when investigating this, I also found something about certificate pinning, which is basically security but the other way around, it means the Xamarin APP will validate if the server certificate is associated with the right server (or something like that), so there is no way of a MAN IN THE MIDDLE Attack.
I found how to implement it here:
https://thomasbandt.com/certificate-and-public-key-pinning-with-xamarin
Question is:
1. Do I need both ?
Something else that I should research for on this journey?
Certificate pinning and Client Certificate Authentication are 2 very different things. Certificate pinning makes sure your app is talking to the server it expects to talk to. It also prevents eavesdropping, which is known as a 'Man in the middle' attack. I just recently wrote an article about this on my blog.
Client Certificate Authentication works the other way around. It adds an extra layer of security so your server can be sure only clients that have the certificate can communicate successfully with it. However, since apps can be decompiled without a lot of effort, this client certificate can 'easily' be obtained by a malicious user. So this isn't a silver bullet.
From my experience, Client Certificate Authentication is often used in enterprise apps, when there is an Enterprise Mobility Management solution in place (eg. Mobile Iron or Microsoft Intune or others), where the EMM solution can push the certificates to the users device out of band.
Should you use both? That really depends on the requirements of your customer, since they mitigate 2 very different problems.
The Web API link you included looks like it should do the server job properly at first sight. This article also includes how to generate a client certificate with a Powershell command.
Generating a client side certificate:
Use the Powershell command in the article that you referenced in your question.
Otherwise, this gist might help you on your way.
Installation:
Add the certificate file to each platform specific project as a resource. This is usually done in the form of a .p12 file.
Usage:
That all depends on which HttpClient you are using.
If you use the provided Web API solution, you should add the certificate contents as a X-ARR-ClientCert header with each request.

Encryption in an open-source program?

Currently I'm developing a Node.js webserver-app that I then want to make available for download and use. This app should feature accounts, so that you can log in with your account on the website created by the server.
Since that would require a password, I also have to think about security obviously. But now, I don't really know how I should protect the password while sending and receiving it.
For storage, I was about to simply create a hash of the password and store that hash somewhere, but what about the transfer?
I was thinking about SSL/https, but this would require a SSL certificate, and even if I got it for free somewhere, I couldn't share it in an open-source app(?).
I could also somehow hash the password in the website, and then just send the hash to the server, but I think this wouldn't be the highest standard of security as well, would it? Considering that no SSL would cause more disadvantages than just worse/none encryption.
Any ideas?
I was thinking about SSL/https, but this would require a SSL certificate, and even if I got it for free somewhere, I couldn't share it in an open-source app(?).
Use SSL/TLS. Even if it's an open source app, it doesn't mean that you need to share your private key too. This would undermine the whole concept.
Open source means that you share the code with some license. What the licensor does with it is not your consern as long as they conform to the license. If they want to use their own instance of your software under their own domain, they will have to create their own certificate (under their domain).
I could also somehow hash the password in the website, and then just send the hash to the server, but I think this wouldn't be the highest standard of security as well, would it? Considering that no SSL would cause more disadvantages than just worse/none encryption.
This is no solution, because you now changed the thing you want to protect to something else. The model doesn't change just because you hash it on the client. Now you need to protect the hash on the transport channel which is actually the same problem as you would have had before with sending a password.
Currently I'm developing a Node.js webserver-app that I then want to make available for download and use. This app should feature accounts, so that you can log in with your account on the website created by the server.
Federated accounts
If you want federated accounts across multiple instances of your app which are hosted by different parties.
You could look into OpenID as an identity provider for all instances of your app. You would then either require that users use a known OpenID provider or you setup your own default provider. You could release the code for your provider as open source, but it wouldn't be necessary for the app to function.
If the OpenID interface is not enough, there is always a way to establish a pairing between instances of your app. You would have to build an interface where different instances may share data.
Unconnected instances
If this is only about securing the communication without SSL/TLS, then I must say, this is impossible in the general sense.
You could however let every student register in person and use that password on client and server to derive a shared secret key (i.e. for AES). Then you could use CryptoJS to encrypt everything with AES and send it using AJAX. The problems are of course that (1) there must be a person that handles the registration and (2) this is vulnerable to man-in-the-middle attacks, because JavaScript crypto is bad.
Good thing is that Let’s Encrypt will be online soon. It will enable a semi-automated way to request free certificates for your domain. It will be so easy that you can do this as part of the normal NPM install workflow.
http://letsencrypt.org works great for this and is now available (I understand I am a little late to this one.)
You can check out https://github.com/DylanPiercey/auto-sni for automated Letsencrypt certificates.

Digitally Signing Data in a web app

I have a web application where some data (not file) needs to be digitally signed using a PKI Private Key. The PKI Certificate & Private Key will be in a USB Cryptotoken which registers the certificates with the browser when inserted into the USB slot. This eases the pain of doing authentication using the certificate because I do that by trigerring ssl-renegotiation in my Application.
However, using a certificate for digital signing seems to be a bit more tricky. I can think of several ways to do this
CAPICOM - http://en.wikipedia.org/wiki/CAPICOM
This will work for browsers which support CAPICOM (eg. IE). However it seems that Microsoft has discontinued this.
Mozilla Crypto Object - https://developer.mozilla.org/en-US/docs/JavaScript_crypto
WebCrypto API - this is not yet supported by most browsers.
A custom Java Applet or some opensource freely available JavaApplet control.
Any other options?
I am trying to figure out what is the common, convenient and secure way of doing this in a web-application.
Note:
I am OK with just supporting the popular browsers.
I am signing a small piece of data - say 100-200 bytes rather than a file.
I would prefer PKCS#7 signatures.
[Disclosure: I work for CoSign.]
The problem that you're running into is a common one with old-style PKI systems that store the signer's private key at the boundary (eg in a smart card, a token, etc). This system was designed when the PC (and apps running on it) was the focus. But that isn't true this century. Now either the browser or the mobile is the focus.
You have tension between the nature of web apps (they're either running on the host or are sandboxed JavaScript on the browser) versus the idea of local hardware that "protects" the private key.
Breaking out of the browser's sandbox
One design direction is to try to break out of the browser's sandbox to access the local hardware private key store. You've listed a number of options. An additional one is the Chrome USB access library. But all of these solutions are:
Limited to specific browsers
Hard (and expensive) to install
Hard (and expensive) to maintain
High level of administrative overhead to help the users with their questions about keeping the system working.
Re your question 5 "Any other options?"
Yes: Centralized signing
A better option (IMHO) is to sign centrally. This way the keys are kept in a centralized FIPS-secure server. Meanwhile, the signers just use a webapp to authorize the signing. The signers don't need to hold the private key since it is stored in the secure server.
To authenticate the signers, you can use whatever level of security your app needs: user name/password; One Time Password; two factor authentication via SMS; etc.
The CoSign Signature API and CoSign Signature Web Agent are designed for this. Centralized PKI signing is also available from other vendors.
Added in response to comment
From the 2nd part of your answer - If the certificate is stored in the server and retrieved by authenticating the user by using uname/pwd or with 2FA, then why do digital signing at all? i.e. what advantage does it offer over just authenticating the transaction with uname/pwd or 2FA?
A: In the centralized design, the private key does not leave the central server. Rather, the document or data to be signed is sent to the server, is signed, and then the signed doc or data (e.g. XML) is returned to the webapp.
Re: why do this? Because a digitally signed document or data set (eg XML) can be verified to guarantee that the document was not changed since signed and provides a trust chain to provide assurance of the signer's identity. In contrast, passwords, even when strengthed by 2FA etc, only provide the app with signer identity assurance, not third parties.
PKI digital signing enables third parties to assure themselves of the signer's identity through the verification process. And the strength of the assurance can be set, as needed, by choosing different CAs.

Sending an Internet request without prompting

In my application, I just want to upload some data on the server without interacting with the user.
How do I silently upload data on the server in J2ME without asking the user for Internet usage?
In order to upload silently, the user must approve at least once that it allows you to connect to the internet, as specified by the MIDP 2.0 Security Architecture.
First you have to sign your Midlet with a certificate from a Certificate Authority (commonly refered as CAs) as Verisign, Thawte, Java Verified, etc. You have to choose your CA depending on the devices you are targeting. The device will just recognize the CAs installed as root certificates. If it doesn't have the root certificate of the CA you chose, it will not be a secure third-party application. This is explained in simple steps in the Nokia Wiki
The second step is to set in your JAD file the next line
MIDlet-Permissions: javax.microedition.io.Connector.http
This will ask for http connections permission since it is installed.
In this way the user will just be noticed once, and will be allowed to set the permission permanently. Some devices will not allow a permanent permission if the application is not signed.
This is impossible. All the phones ask the user before letting an application use internet services.
One possibility could be signing the application somehow, but that would work on very few phones, if any.
If your application is signed by Java Verify or similar you will be able to let the user say they allow all future http connections, rather than having to authorise them all singularly.

Client Certs on IIS - not sure I get it - experiences please?

Looking for some advice about the use of client certs to retro-fit access control to an existing app.
Our company has an existing intranet app (classic ASP/IIS) which we licence to others. Up till now it's been hosted within each organisation that used it and the security consisted of "if you're able to access the intranet you're able the access the application".
I'm now looking for a way to host this app externally so that other organisations who don't wish to host it themselves can use it (each new client would have their own installation).
All user in the new organisation would have a client cert so what I'd like to do is use the 'Require Client Certificate' stuff in IIS. It allows you to say "if Organisation=BigClientX then pretend they're local userY".
What I would prefer is something that says "if Organisation=BigClientX then let them access resources in virtualdirectoryZ otherwise ignore them".
I would be very happy to buy an addon (perhaps an ISAPI filter ?) which would do this for me if that was the best approach. Any advice / war stories would be welcomed.
You likely want to do this. client certs are really intended for a second factor of authentication, but not the primary source. To say it differently, you still need to configure your app for basic or forms authentication.
The technology behind public/private keys is rock solid. However, you need a very mature IT organization who is dealing with certificate lifecycle management. If you do not have this, you will get untold failure scenarios because the certificate was expired, wasn't copied to the new computer, etc.
This is especially true in your scenario where your application is internet facing (in thee 'hosted' scenario) - you have little control about the issuance of the certificates to your users.
I've done something similar...
Generate the certificates internally from your org's domain controller. Export them both as PFX format for distribution, and CER format for you to import in IIS.
Distribute the PFX format exports along with the CA certificate for your DC, so your customers machines will "trust" your CA.
Now in the app properties IIS, go to the Directory Security tab, and under "Secure Communications" click "Edit". In there, click "Accept client certificates", "Enable Client Certificate Mapping", then "Edit".
Under the 1-to-1 tab, click "Add" and import the CER file. Enter the account you'd like to map this certificate to.
As for the "let them access resources" I'd advise doing that by the user account they're mapped through - that is, you can provide access to resources based on that account either through NTFS permissions, or through code by identifying the security context of the logged-in user.

Resources