Search code examples
iosobjective-cweb-servicescommoncrypto

How to send CommonCrypto POST request using AES Crypto in Objective c?


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.


Solution

  • 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.