4

I just try to send secure request from iOS app to php platform web services in objective c. I trying since 2 days but i did not find the logic or anything how to achieve this:

Following is a Swift Code that using CryptoSwift Framework

func HTTPPostJSON(url: String, jsonData: Dictionary<String, AnyObject>, type: String = "POST", encrypt: Bool = false, callback: (String, String?) -> Void) {
        if Debug().state {
            print("** Start HTTP")
        }
        crypto_enabled = encrypt
        let req = NSMutableURLRequest(URL: NSURL(string: url)!)
        req.HTTPMethod = type
        req.addValue(self.dataType, forHTTPHeaderField: self.headerType)
        let json: JSON = JSON(jsonData)
        //        var data: NSData = NSJSONSerialization.dataWithJSONObject(json.object, options: nil, error: nil)!
        var data: NSData = NSData()
        do {
            data = try NSJSONSerialization.dataWithJSONObject(json.object, options: NSJSONWritingOptions.init(rawValue: 0))
        } catch {
            print("JSON to NSData error: \(error)")
        }
        if Debug().state {
            print("JSON Object: \(json)")
        }
        if crypto_enabled {
            if Debug().state {
                print("Encryption enabled")
            }
            let iv = Cipher.randomIV(AES.blockSize)
            //            println("UInt8 IV: \(iv)")
            let iv_size = iv.count //count(iv)
            print("IV Size: \(iv_size)")
            var key = [UInt8] (self.secret.utf8)
            //            println("UInt8 Key: \(key)")
            let secret_len = self.secret.characters.count
            print("Key length: \(secret_len)")

            if self.secret.characters.count != 32 {
                if Debug().state {
                    print("Hashing Secret")
                }
                let data: NSData = self.secret.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
                //                key = (CryptoSwift.Hash.md5(data).calculate()!).arrayOfBytes()
                key = (CryptoSwift.Hash.sha256(data).calculate()!).arrayOfBytes()
                if Debug().state {
                    print("New UInt8 Key: \(key)")
                    let new_key_len = key.count
                    print("New Key Length: \(new_key_len)")
                }
            }

            let aes = AES(key: key, iv: iv, blockMode: .CBC)!
            var encrypted: [UInt8] = []
            do {
                encrypted = try aes.encrypt(data.arrayOfBytes())
            } catch {
                print("Encrypt data failed: \(error)")
            }
            // IV
            let ivData: NSData = NSData.withBytes(iv)
            //            println("IV in NSData: \(ivData)\n")
            let ivBase64 = ivData.base64EncodedDataWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
            //            println("IV in Base64: \(ivBase64)\n")
            let ivBase64String = NSString(data: ivBase64, encoding: NSUTF8StringEncoding) as! String
            //            println("IV in Base64 String: \(ivBase64String)\n")
            // cData
            let cData_Data = NSData.withBytes(encrypted)
            // 1st cData Base64 encoding
            let cData_Base64 = cData_Data.base64EncodedDataWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
            let cData_Base64String = NSString(data: cData_Base64, encoding: NSUTF8StringEncoding) as! String
            // 2nd cData Base64 encoding
            let cData_Base64String_Data = cData_Base64String.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
            let cData_L2_Base64 = cData_Base64String_Data.base64EncodedDataWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
            let cData_L2_Base64String = NSString(data: cData_L2_Base64, encoding: NSUTF8StringEncoding) as! String

            let cipheredDict: Dictionary<String, AnyObject> = [
                "iv": ivBase64String,
                "cData": cData_L2_Base64String // cData_Base64String
            ]
            var cipheredJSON: JSON = JSON(cipheredDict)
            //            let cipheredData: NSData = NSJSONSerialization.dataWithJSONObject(cipheredJSON.object, options: nil, error: nil)!
            var cipheredData: NSData = NSData()
            do {
                cipheredData = try NSJSONSerialization.dataWithJSONObject(cipheredJSON.object, options: NSJSONWritingOptions.init(rawValue: 0))
            } catch {
                print("Ciphered JSON to NSData error: \(error)")
            }
            //            if Debug().state {
            //                println("Ciphered Data: \(cipheredData)")
            //            }
            data = cipheredData
        }
        //let jsonString = json //self.JSONStringify(json)
        //let data: NSData = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
        req.HTTPBody = data
        self.HTTPSendReq(req, callback: callback)
    }

I try to implement in objective c by using MIHCrypto

 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://00.00.00.000/member/slogin"]];


    NSMutableDictionary *parameters = [NSMutableDictionary new];
    [parameters setObject:@"POS" forKey:@"from"];
    [parameters setObject:@"52001" forKey:@"username"];
    [parameters setObject:@"111111" forKey:@"password"];

    // Specify that it will be a POST request
    request.HTTPMethod = @"POST";

    // This is how we set header fields
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
     NSError *jsonSerializationError = nil;

    NSString*secrate = @"keythatuser";



    // Convert your data and set your request's HTTPBody property
  NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:&jsonSerializationError];



    NSError *error;
    NSData *encryptedData = [RNEncryptor encryptData:jsonData
                                        withSettings:kRNCryptorAES256Settings
                                            password:secrate
                                               error:&error];



    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [conn start];

Frankly i have no idea how to do parse it can you please guide me for encrypt PHP server request and after decrypt it's encrypted response.

Nitin Gohel
  • 49,482
  • 17
  • 105
  • 144
  • It is best to avoid using CryptoSwift, amoung other things it is over 500 to 1000 times slower than Common Crypto based implementations. Apple's Common Crypto is FIPS certified and as such has been well vetted, using CryptoSwift is taking a chance on correctness and security. – zaph Dec 15 '15 at 12:37
  • do you have any example code or article for it. becouse i did not find anyting related to objective c parsing thing. – Nitin Gohel Dec 15 '15 at 12:49
  • 1
    Why is https insufficient? – zaph Dec 15 '15 at 12:55
  • What does 'objective c parsing thing" mean? – zaph Dec 15 '15 at 14:22
  • i never done this befor and i have no idea about so i asking for any sample and more hind about it how to do with objective c – Nitin Gohel Dec 15 '15 at 15:00
  • Again, why not just use https requests in place of http requests. See my answer. – zaph Dec 15 '15 at 15:02
  • @zaph you are right but client already develope the webservices and in swift that working as i attached in qustion now i trying to parsing in objective c – Nitin Gohel Dec 16 '15 at 11:16
  • That's why we can't have nice (secure) things. See this [SO answer](http://stackoverflow.com/a/25755864/451475) for a Swift AES example. Suggestion: separate the encryption into separate method from the wrapper code such as preparing encryption arguments such as JSON, Base64, data. make each method have a Single Responsibility. – zaph Dec 16 '15 at 14:37

2 Answers2

2

We can do it by creating a helper class of Swift in Objective-C project.

Install pods in your project with

platform :ios, '8.0'
use_frameworks!

target 'CryptoTest' do
    pod 'CryptoSwift'
end

Add a helper swift file with bridging header

For that go to the Settings > Packaging > Defines Module = True

enter image description here

Now import the CryptoSwift in The Helper File

For Example :

//
//  CryptoHelper.swift
//  CryptoTest

import UIKit
import CryptoSwift

class CryptoHelper: NSObject {
    func cryptTest(){
        /* Hash enum usage */
        let input:[UInt8] = [49, 50, 51]

        let output = input.md5()
        // alternatively: let output = CryptoSwift.Hash.md5(input).calculate()

        print(output.toHexString())
    }
}

Now use that helper file at any of your Objective-C (.m) file

For Example:

#import "ViewController.h"
#import "CryptoTest-Swift.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    CryptoHelper *testCrypt = [[CryptoHelper alloc]init];
    [testCrypt cryptTest];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Here #import "CryptoTest-Swift.h" means #import "YourProjectModuleName-Swift.h".

Hope it helps you.

Ashish Kakkad
  • 23,586
  • 12
  • 103
  • 136
1

If all you need is to send secure request to a web server just use https. Using https encrypts the entire transfer and even any query parameters. You can not do better.

For added MITM security pin the certificate.

If you need more security use RNCryptor which is available in several languages for several platforms. It is well secure, well vetted and under current development/maintenance. It provides all the details such as a random iv, message authentication, key extension and versioning for strong security.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
zaph
  • 111,848
  • 21
  • 189
  • 228