How to Make Secure Calls to APIs from External Servers

Rodrigo Reis - Senior Software Engineer

We are listening to our customers. One of the most requested features is now available in the Mobile SDK 1.5: how to make secure call to APIs from externals servers (other than MAG), including public servers. In previous versions, you could only make secure APIs calls for applications that were enrolled with the MAG server.

With the new MASSecurityConfiguration object, you can customize the following security items for API calls:

  • SSL pinning method
    • Certificate (as an array of string, like in msso_config)
    • Public Key Hash (as a string)
  • Evaluate the domain name of the certificate on the server trust (boolean)
  • Evaluate the certificate against root certificates on device (boolean)
  • Default credentials injection on API calls (boolean) 

For this release, the Mobile SDK supports only the Certificate Signature algorithm SHA256withRSA with Key RSA 2048 bits (the most used algorithm). We are looking at other algorithms like ECDSA (Elliptic Curve Digital Signature Algorithm) and ECC (Elliptic Curve Cryptography).

Get Started

So, now let’s go direct to the point and see how it works with a step by step sample. We choose a public API that does not require authentication or enrollment to simplify. In this sample we are going to add the ipify as trusted source by creating a MASSecurityConfiguration object and add it to MASConfiguration. Then we will invoke the API to return a JSON containing the IP address of the caller. This step by step will assume you were exposed to MAS SDK before, but if you never used it don't worry, we will guide you on where get assistance to complete each step.

Before start with iOS part, we need to obtain the Certificate and Public Key Hash of our target host to add the security configuration. So in the steps bellow, we are going to use the OpenSSL to extract those.

Note: The macOS already includes the OpenSSL, if you are using another Operating System please refer to openssl.org.

Get Public Key Hash

1. Open a terminal and type the following OpenSSL command to extract the certificates from the ipify host and store them in a .pem file.

$ sudo echo -n | openssl s_client -connect api.ipify.org:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./api.ipify.org.pem

If you list the items in current folder, you will see the file, api.ipify.org.pem.

2. Extract the public key hash from api.ipify.org.pem using the following OpenSSL command.

$ openssl x509 -in api.ipify.org.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64

3. Copy the public key hash from the command (to use in a later step).

alt

Configure the Public API Host

Now the best part – let's create our app. To make it quick and easy, we will use the MASBasic app template.

  1. Create a new iOS project using the "MASBasic" template. Create an App Using the Mobile SDK Templates.
  2. After you create the project, make sure to run the "pod install" to include the MASFoundation framework into your project. Step 2: Add the Mobile SDK Libraries and Build the Project.
  3. Time to include the msso_config.json file. Never heard of it? Prerequisites.
  4. Now you are ready to add some code. But first, let's run the app to see if it builds successfully. You should see a screen like the one below.
alt

5. It works! Ready to code? So here we go. Open the MASMainViewController and locate the viewDidLoad. Inside the [MAS start:] method remove or comment out the code to Handle Success initialization of the SDK.

6. After the handle success block, add the following code. This code will create a NSURL object containing the host of ipify.

//
// Create a URL from string with schema, target host and port
//
NSURL *url = [NSURL URLWithString:@"https://api.ipify.org:443"];

7. We will use the NSURL object created in the previous step to create the MASSecurityConfiguration object and include the Security settings for this server. Now we will use the Public Key Hash extracted from ipify certificate.

//
// Configure security settings for the target host
//
MASSecurityConfiguration *securityConfiguration = [[MASSecurityConfiguration alloc] initWithURL:url];
securityConfiguration.isPublic = TRUE;
securityConfiguration.publicKeyHashes = @[@"mVwW3YCRAC0H5FvMmXI1QjW+sXpzlymuHgJ+GpAN7Lk="];
[MASConfiguration setSecurityConfiguration:securityConfiguration];

Note: Make sure to set isPublic to TRUE when invoking hosts other than the primary gateway. The default value is FALSE, which means the credentials are sent along with the request. For external hosts, you probably won't want to do this.

8. Finally, let's add the code to invoke the API and display the result.

//
// Call the public endpoint and handle response
//
[MAS getFrom:@"https://api.ipify.org?format=json" withParameters:nil andHeaders:nil requestType:MASRequestResponseTypeTextPlain responseType:MASRequestResponseTypeJson completion:^(NSDictionary *responseInfo, NSError *error) {

//
// Handle error
//
if(error)
{
NSLog(@"MAS get - completed with error: %@", error);

return;
}

//
// Obtain ip from MASResponseInfoBodyInfoKey
//
NSDictionary *result = [responseInfo objectForKey:@"MASResponseInfoBodyInfoKey"];
NSString *ip = [result objectForKey:@"ip"];

//
// Display a dialog to user with the IP
//
dispatch_async (dispatch_get_main_queue(), ^
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"My IP address:"
message:ip
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:defaultAction];

[blockSelf presentViewController:alertController animated:YES completion:nil];
});
}];

9. Let's run the app and see if it works.

alt

Congratulations! You’ve successfully invoked a public API using the Mobile SDK.

You can download the completed project here. Remember that you will need to change the bundle ID, run the pod install and add the msso_config.json file to make it work.

Rodrigo Reis - Senior Software Engineer

Rodrigo works in the API Management Business Unit where he works on mobile technologies on the Mobile App Services product. He graduated from the Computer Science Department at Faculdade Ruy Barbosa, Salvador in 2006. Rodrigo is a technology enthusiast and developer by passion, who has dedicated the last 20 years to the IT industry. Before join CA, Rodrigo worked for ten years at IBM architecting and building Collaboration solutions for enterprises companies in Latin America and USA. He has been "playing" with mobile technologies since the old PDAs (Palm and Pocket PC) to iOS, Android and Windows platforms.

Chat
What would you like to chat about?
Support
Contact
Call us at1-800-225-5224
Call us at1-800-225-5224
Contact Us