Encrypt json data with secret key on IOS and decrypt it with node js - ios

I need to protect my API for CSRF on post and put requests.
To do that, I think the mobile device (example iOS) need to send to the API server (node.js) a token. This token must be encrypted and contain a JSON data that will be decrypted server side.
To decrypt the data, the mobile device use the same secret key that the sever know.
For example : {_csrf: 123456789} will be decrypted from the token sent via the mobile device and checked by the API if it match.
Is it the right way ? If not what is the right way ?
How I can encrypt a Jon data on iOS and decrypt it on node.js ? (JWT Token does not have library for iOS)
Can you provide me a example code to encrypt data on iOS et decrypt on node.js ?

Just use https, it encrypts everything, even any query string.
The content is encrypted with a random symmetric key and that key is encrypted with a asymmetric key from the certificate. Additionally the symmetric key has a short lifetime. Additionally you do not have to implements and encryption routines.
Also note that iOS9 will by default require https to be used for all connections, any http connections will need to be white-listed in the plist.
If you do your own encryption you immediately have a problem sharing the encryption key between the device and the server. This is not an easy problem to solve.

When accessing the API from a browser page, to protect against CSRF, you can send a token in HTTP headers, for example, X-CSRF-Token, or, use a cookie.
For example, have your server send the CSRF token in an HTTP response using the X-CSRF-Token header. You can have your page send it back in the JSON on the POST or PUT. Or have your page read it from the cookie and put it into the JSON.
(HTTPS from the browser will not protect against CSRF, since any script on any other site running in the same browser can POST to your HTTPS server freely. Your page needs to have a token that no other page in the same browser has access to.)

Related

URLSession | Authentication Challenge Response | NTLM

I am aware of How to Respond to an Authentication Challengelike we have NTLM Authentication as there are 3 options.
Provide authentication credentials.
Attempt to continue without credentials.
Cancel the authentication request.
But just want to know the thoughts here, when we go with the first option Provide authentication credentials we pass the username and password URLCredential is there any possibility of leakage of credentials, is it secure to pass the credentials, what is happening behind the screens? how Apple network API sending the credentials to the server?
Yes, we can set the policies like server domain, failure count etc. but from the security point of view is it safe? from Man in Middle Attack (MIMA) or anything else?
Maybe the way I have posted my question is not clear but I was looking more from the Application credential security point of view with NTLM Authentication and after lots of Google, I have found, how’s NTLM works and it’s pretty interesting to see that client don’t share the password with the server. here are the steps as follow.
The client makes the request to the server.
The server needs to validate the user because there is no identity so server generates 16 bytes random number called as the challenge and sends it to the client.
Client hash this challenge with the user’s password and return it back to the server that is called the response it also includes username as plain text and challenge sent to the client.
The server sends everything to the domain controller and it uses the username to retrieve the hash of the user’s password from security account manager database and hash the challenge.
Domain controller shares the response back to the server if they are identical then authentication is successful otherwise a failure.
So the interesting part is here that Network API doesn’t share the password with the server it means it very secure.
I hope it will help others, For More.
There are multiple types of challenges, and the answer to your question depends on what type of challenge you're talking about. Each challenge has a protection space, which basically tells what type of challenge you're responding to.
To answer your question for the most common protection spaces:
Basic password-based authentication (NSURLAuthenticationMethodHTTPBasic): The credential you pass is sent in cleartext to the server (HTTP) or encrypted by the session key (HTTPS).
Digest authentication (NSURLAuthenticationMethodHTTPDigest): The credential you pass is cryptographically hashed with a nonce provided by the server, and only the resulting hashed token gets sent over the network.
NTLM authentication (NSURLAuthenticationMethodNTLM): The credential you pass is cryptographically hashed with a nonce sent by the server, and only the resulting hashed token gets sent over the network.
Client Certificate authentication (NSURLAuthenticationMethodClientCertificate): The certificate is sent to the server, but not the private key data. The client uses the private key to sign the prior TLS handshake data as a means of letting the server verify that the client really does have the private key associated with that cert.
Server certificate validation (NSURLAuthenticationMethodServerTrust): If you pass a certificate obtained from the server, you MUST validate it first, or else you effectively reduce the level of security to that of HTTP (i.e. any server can send any cert and you'll be saying to trust that cert when talking to the server).
The list above covers the most common protection spaces. Kerberos is its own animal, and I don't know anything at all about how that works. And there's also the "Form" protection space, which is just a placeholder for custom authentication that you can use in various parts of your app's code, but is not actually supported in any meaningful way.
It is worth noting that Basic, Digest, and NTLM authentication provide no protection against man-in-the-middle attacks if the attacker can alter data in transit, because the authentication token provided does not depend on the rest of the request in any way. Thus, these are really suitable only for use over an encrypted channel (HTTPS).

Sending Data from an iOS App to an HTTPS Service

I have developed an iOS app using Xamarin and I am unsure about how encryption would work when calling a service that uses HTTPS.
On my end I do nothing particularly special: I utilize a RestClient and add the credentials to the body of a json serialized request. I then post it to the HTTPS service.
Is this safe or should I be doing more? I am not sure if iOS handles the rest for me in terms of encryption.
Answer
Yes, by using HTTPS, you are most-likely safe. However, there are a couple things to verify to ensure that there are no security leaks.
More Info on TLS
Communication with secure HTTPS enpoints encrypt the header and body of the message by default using TLS.
HTTPS consists of communication over Hypertext Transfer Protocol (HTTP) within a connection encrypted by Transport Layer Security. Source
Things To Verify
Do Not Use Sensitve Data in the URL
The Url of the HTTPS endpoint is not encrypted. It is important to never put any sensitive data into the Url of the HTTPS enpoint. To ensure sensitive data is encrpyted, put the data in the message body.
For example, if you are validating a user's login (username: user1234, password: password1234), do not send the username/password as a url parameter. Instead, serialize the username and password data, and set it as the HttpContent of the HttpClient.
Bad: https://myApiEndpoint.com/getIsUserValid/user123/password1234
iOS HttpClient Implementation
Ensure that you are using NSUrlSession for the iOS HttpClient Implementation.
NSUrlSession will use TLS by default when communicating with secure HTTPS endpoints. As of iOS 10, NSAppTransportSecurity will not allow communication to non-secure HTTP endpoints by default; communication with non-secure HTTP enpoints can be enabled by updating NSAppTransportSecurity in Info.plist, Apple Documentation.
You can verify NSUrlSession is being used in the iOS Build Settings (screenshot below).
When using HTTPS everything except the server address is encrypted during transit. The encryption is totally transparent to the client and server.
Example: for the URL https://myApiEndpoint.com/getIsUserValid/user123/password123‌​4 only myApiEndpoint.com is not encrypted, the rest of the URL is encrypted.
In order to protect against MITM attacks pin the server certificate, that is verify that the certificate received on the request belongs to the correct server.
If you control the server use TLS 1.2 and Perfect Forward Secrecy.

Decoding HS256 in client side?

I'm using json web tokens for my app.
When i login to my site and want to see who is the user logged in, i have a previously stored token with all the needed data in it encoded in HS256.
Should i use this token payload to show "Hello ..." and the user name which is inside the payload, or should i decode the token server side and retrieve the user data from there?
Is there any client-side library to decode HS256 for me to use?
Or is it bad practice and should be avoided.
JWT is self-contained and is protected with a digital signature. You can perfectly use the information contained in the token, but you should validate the expiration time and to ensure that digital signature has not been altered.
To verify the signature on the client side you need the key was asymmetrical and use the public key to verify. May be send the token to server save you problems. Depends on the operation could take the risk, as long as the token is used for autenthication on the server and it performs the validation
Is there any client-side library to decode HS256 for me to use? Or is it bad practice and should be avoided.
In fact, you do not need any library. The payload is base64 url encoded, and can be easily decoded in any programming language. You would need a library to verify digital signature. Take a look at jwt.io

Is it safe to append sensitive data to the end of https urls used in an iOS App?

I am using an iPhone app to ping a "https" URL that looks like the following:
https://domain.com/server/unique-id/SecretInformationString
I'm assuming server logs would be vulnerable, as well as iPhone history perhaps... but would someone outside of the local network have any idea of what "SecretInformationString" is?
Information added to the end of the URL will not be secure as the URL itself is sent in plain text before your request is encrypted.
If you were to make a POST request with the secret values instead the URL will still be visible to the outside world in plaintext however your post data would be encrypted.
Edit: If you are making multiple requests with the same secret data (i.e. you are using it as an authentication token) you may want to consider using a secure cookie.

Sending Device Token Safely for APNs

For iOS applications that require push notifications, it must first request the user for permission to do so. After that, a device token is generated and with this, the remote server may communicate to the user through this token.
I have read a similar question here and I do not feel it is enough. The picture below is a trusted certificate, it allows me to view all traffic that happens on this device.
With Fiddler2 as well as CertMaker, I can sniff HTTPS traffic, which means the client can probably know what data they are sending, and to where.
My question is, knowing that SSL is not secure from protecting my clients from seeing what I send to the remote server, should I simply encypt with a secret key found within my application?
Such as encrypt("device_token","secretkey_a0a0a0a") (pretend this is Objective-C)?
Couldn't someone just find that key within my application? I also read this question, and it seems that it would be possible to get back the secret key.
My plan for this goes like this:
Within the iOS application, Generate a random string named activate.
Encrypt (not hash), the token by the random string and a secret key that I only know. (secretkey_a0a0a0)
Send the encrypted string along with the generated randomly generated string (active).
Within serverside, I check if I can decrypt a valid token from using the active and my secret key.
I save the token in my database if it is valid.
This prevents people from random entering tokens yes, however, secretkey_a0a0a0 is a string literal. It's very possible to get this within the application binary itself.
My question is, how do I protect this secret key? The answer can also be, how can I prevent people from sending invalid tokens to my server as well.
I have heard of encryption, but doesn't that only apply to resource files?
How should I approach this?
If you do SSL-Pinning ( AFNetworking has this implemented ) you won't be able to (in a reasonable timeframe) sniff the https traffic between the client and server if you don't have the servers private key.
If your fear is that man in the middle can steal your token and send fake push notifications to users of your application, be sure that this cant happend. Since requests to apple apn servers must be signed with pem file, the main concern should be how to keep certificate file secured, and not apn token. If you want to prevent writing invalid tokens in your database then you should implement some CRC or odd/even bit mechanism.
You might want to check the security section in the Push Notifications Guide, in particular the section titled "Token Generation and Dispersal".
The device token is generated by the device connecting through the Apple's APNS. My guess (they don't say in the docs) is that it's unique for a given app identifier.
The APNS then will probably match those identifiers with the pem certificate you use to communicate with it thus validating that the push notifications are actually originating from your app.
Encrypting the device token seems overkill in this scenario.
To prevent someone maliciously spamming your server with tokens, I would hash the token when a secret key and send both the token and the hash to the server. You can then hash the token again on the server, with your secret key, and check that the request is valid.

Resources