Should APNS Tokens be encrypted? - ios

So, I was wondering, since users send their APNS tokens to the APNS provider in order to receive push notifications, should the tokens be encrypted? Is SSL necessary?
From what I figure is that there is no real sensitive data in the token. If someone actually managed to sniff the token from a user, he still would have to obtain my push certificate. And if he managed to do that (he won't ;-)) all he could do is send spam notifications to this particular user. Is that correct? Or did I miss something?
Also, I assume that it's not possible to identify a device (or more importantly, its user) based on an APNS token?
So, I want to assure that, if someone sniffs a push notification registration from one of my clients (the registration contains the APNS token and the information the user is interested in, and the connection is unencryped so everything is readable in plain text) ...
he still has to obtain my push certificate to be able to bother my client in any way
he knows that someone is interested in this information, but has no way to identify who my client is
Can I rest assured?
Thanks in advance!

SSL is almost never a BAD idea. Lack of SSL means your users will be susceptible to all sorts of nastiness like DNS poisoning, man in the middle, or sniffing.
Maybe you're worried about the cost of an SSL cert, or the overhead on your servers? I don't know - but I'm just sayin' - probably worth considering if you're getting paid to provide some service or are collecting personally identifiable information.
Otherwise your points in the post were pretty much right on. The fact is someone would need your push certificate to send out those messages to those users.
Also, I assume that it's not possible to identify a device (or more
importantly, its user) based on an APNS token?
Prior to iOS 5, that ID was consistent across all apps - so aggregate stats companies were able to use the ID to identify a specific user somewhat... at least to know "this is the same person". But that changed recently, and it's now a random per-app ID.

Related

APNS with Firebase version 3

I've set up Firebase to send push notifications to users of my app. However, I'm not sure what's best practice regarding user-to-user communication, such as chat clients. Should I get the device token at each startup of the app and use that for sending, or should I create a new topic for each "chatroom" that both parties are required to subscribe to? For instance when accepting a chat request.
If the first option is the best, how does this work? If the device is assigned a new token upon app startup, how can I be sure a given ID points to a specific device? The whole concept seems fragile - but could someone guide me to the most efficient solution?
I'm only looking to send chat messages / chat invites with push
Depending on the size and the privacy of the chatroom you can choose between using:
topics made for big groups, and without protections on joining / leaving
device tokens that you need to store in your server implementation.
On the plus side they allow you to control the who is receiving the
messages, and to send messages to individual device.
The device token does not change every startup.
It is created when the application is launched for the first time, and can be updated in special cases. When the token change (again, this is rare) the FirebaseInstanceIdService.onTokenRefresh() callback is called.
In a generic chat application you might want to:
first authenticate the user with your login system
upload to your server the mapping user-id > device-token
send messages to the users via the FCM server-side APIs.
Update to address one of the comments:
The server-side API allows to send the same message to multiple tokens in the same HTTP request. See registration_ids in https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json
You should not use the server-side API in the client, because that would require you to add the API-KEY in the application which is a security issue (people could decompile the app and read the key)
The storage structure is up to you. For user-id > multiple-device-tokens a dictionary could work.
If the token are non reusable. So it's safe to send messages to expired token.
Token generation requires internet connectivity, so it could take some time.
To handle token after user registration see this question:
How to launch FCM ID Service only after a particular activity is triggered?

How to save confidential data on iOS? Keychain or Outh2? Thanks.

As you know many apps use keychain to save user login name and password, but is it really safe? especially on device jail break mode. So another solution is to use Outh2 protocol to save those confidential infomation on server side which needs many changes on both client and server side (for my app).
How do you guys handle this tough issue? Anyone who knows please share and thanks in advance.
Keychain:
It has two level encryption options
lock screen passcode as the encryption key
key generated by and stored on the device)
But when the device is jailbroken its not safe too.
oAuth:
Eventhough you store credentials in server you'll have to save the OAuth TOKEN in client side there is no place better than keychain to store it in client side.So now comes possibility of extracting the TOKEN on jailbroken device.
As far as I know in most apps they use one of these approaches.
If you need those data to be very very secure.
Suggestions:
Store OAuth token in server not in client
Store the Encrypted Credentials in Keychain and store the encryption key in server.This approach would be easy for you since you said adopting OAuth is hard for you.
Note:
There are some open source libraries available which detects if the device you run or app is cracked if so you can take action like deactivating TOKEN,deleting critical resources,locking app etc.

Implementing Two Factor Authentication in iPad App

I'm planning introduce two factor authentication to my iPad application. Currently user login to my app using a username and password. That username and password is validate from the back end web server devloped using .Net. If user is authorize to login then he can access the iPad application.
Now I want to introduce two factor authentication to validate user. I want to know what are the options we have here. Since we have user’s phone no with us I was thinking of sending a passcode to his phone each time he tries to login to the iPad application. But iPad doesn’t support sending messages over the GSM/CDMA network. Is there a way to achieve this? (Thought about getting an SMS gateway from the local ISP and writing SMS a server. But it cost more) Third-party module will be ok.
Check google authenticator. https://code.google.com/p/google-authenticator/
I think it is quiet good for two-step authentication.
Here is source code for server side (it is on php but i think it is not big issue to convert it to .NET or another platform) https://github.com/chregu/GoogleAuthenticator.php
As I know it uses Time-based One-time Password Algorithm http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
You can send an SMS to the mobile phone of the user with a code.
After that the user puts the code and the APP validates the code making a request to the server.
The SMS is sended after the user sucessful introduced the username/password.
Other option (less expansive) is to send that code by email.
You should try the google Authenticator
There are other's like https://www.gauthify.com, who offer this service.
You may be interested in looking in this StackOverflow Post.
I cannot fully express how much I am impressed by Twitter's recent TFA implementation, it is extremely convenient and (assuming they didn't botch the protocol) much more secure than many other forms of TFA.
Here's a description written by Wired.
But to summarize you activate a device for TFA and it generates a private (device)/ public (server) key pair. When you try to login after receiving correct username/password credentials the server sends a push notification to the application on any authorized devices encrypted with the public key and the application decrypts the nonce and sends the nonce back to the server and is given a session.
And of course as others have mentioned, there are prebuilt services you can use such as Google Authenticator, but they tend to be clunkier and there are concerns about SMS and TOTP security.
Two Factor Authentication means confirming something the user knows (their password) and something they have in their possession (like a physical key, a badge, or RSA key fob; the important part is it's a physical object other than what you are giving them access into). Sending a push of any kind to the iPad they are using to login to the app defeats the purpose and is no better than single factor (password only). Your only choices are:
Distribute an RSA key fob (or similar). Probably not an option because of the cost & management overhead associated.
Create an authenticator app that only works on a separate device than the iPad with your app on it (along the same lines as the Google Authenticator app). You can probably prevent the authenticator app being run on the iPad by registering a URI scheme for your protected app and trying to open it from the authenticator every time the authenticator is opened. If the protected app opens that means the user is trying to run both on the same device and the authenticator should not validate them.
Send a SMS to their registered phone with an authentication code. By using SMS here you're forcing the user to have both devices to be able to login, which is the key to TFA. Note that a creative user could register a Google Voice number (or similar VOIP with SMS app) on their iPad, thus circumventing the physical aspect of TFA.

How to implement "Two factor authentication" in iOS application?

I am locking my Mac screen with my Mac app. As I enters password it needs to unlock. The password should be generated internally. So I preffered to implement it by using "Two way factor authentication". By this my iPhone app generates a token frequently as I enters the token in Mac application it has to unlock.
I found few APIs like Gauthify and Authy. But they are generating tokens on their own apps(ie.,to get token from authy we need to install authy app in our mobile).
My requirement is without installing those apps,my app need to generate the token and communicate with my Mac.
Please guide me if any one had done it. Good suggestions are appreciable.
All these apps, including Google or any other apis use two step authentication. Here they generate a token with some private key and pass that to end user via sms or mail or any other medium. This sms or mail is registered with user in application database.
There is no need to use such app if you have your same app in your MAC and your ios Device.
You just need to identify how will you pass that key.
If MAC is generating token, and you know which device is trying to connect with MAC, you can send that token in background to that ios Device and match that. If you are using socket connections, this is option for you
When user enters Token, you can make a request to server to check that token. For this you need to send token genereated on MAC to server and save it somewhere. These tokens generally expires after some time, so run cron job to delete such tokens.
The apps you described use 2nd way to authenticate.
Hope this much help you. All depends your requirements and your approach :)
Cheers

Validating GamceCenter user credentials in the backend

I am building a backend for ios apps, that support login in different networks.
Once the user login in to the network the client tells the news to the backend, and this could offer a list of worlds that the user might play, or even delete old worlds.
One way to steal another person's world is by saying that you are his social network id.
To solve that with facebook, we force the client to send us the fb_token, a token provided from facebook to the client, that we use in the backend to ask facebook if that specific user is the one that he told us to be.
If apple doesn't provide a way to validate this I understand that if an iOS app wants to use game center, it is directly forcing the app developer to also use iCloud because apple can validate the user credentials.
Did apple provide any way to validate user credentials?
The client on iOS can retrieve info about the currently logged in player in GameCenter, which has nothing to do with iCloud.
If you want to use iCloud to authenticate, you might have a different player than the one you wanted.
I think the solution is for the client to retrieve the player info in GameCenter, and send it to your server in an encrypted fashion (say HTTPS), including a timestamp and possibly other dynamic information. This way you'll know that the user info is being sent from the client app itself and there is no man-in-the-middle. That's really the issue that you are struggling with: how to ensure that client-server communication is secure.

Resources