6

Data fetched from server using

var request = var request = URLRequest(url: URL(string: "http://www.example.com/test.php")!)   
        request.httpMethod = "POST"   
        let akey:String =  txt_key.stringValue;   
        let email:String = txt_email.stringValue   
        let VAL:String="test"      
        var data="blah"   
        let postString = data   
        request.httpBody = postString.data(using: .utf8)   
        let task = URLSession.shared.dataTask(with: request) { data, response, error in   
            guard let data = data, error == nil else {                                                 /   
                print("error=\(error)")   
                return   
            }   
            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           /   
                print("statusCode should be 200, but is \(httpStatus.statusCode)")   
                print("response = \(response)")   
            }   
            let responseString = String(data: data, encoding:  .utf8)   
            print(responseString)   
        }   
        task.resume()   

Decryption using

   func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
            let cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCDecrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                                      algoritm,
                                      options,
                                      (keyData as NSData).bytes, keyLength,
                                      iv,
                                      data.bytes, data.length,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
                return unencryptedMessage
            }
            else {
                return nil
            }
        }
        return nil
}

Even when responseString is not null,The following code always returns optional("")

 let unencode = String(describing: responseString!).aesDecrypt(key: "123456789012asdsadasd", iv: "iv-salt-string--")

Why is this happening ? Please advice.

techno
  • 6,100
  • 16
  • 86
  • 192
  • Can you print the data returned in your post? try `print(String(data: data, encoding: .utf8) ?? "no data")` – Leo Dabus Oct 11 '17 at 18:25
  • Note that the top level object of a JSON should be an array or a dictionary. You are passing a single string data – Leo Dabus Oct 11 '17 at 18:31
  • @LeoDabus Yes.. if I give print(resultString! ) .It prints the response from the server. – techno Oct 11 '17 at 18:32
  • .not the response the data sorry it is the same – Leo Dabus Oct 11 '17 at 18:33
  • Never use `String(describing:)` ! – Martin R Oct 11 '17 at 18:33
  • Like I said you need to make sure you are passing the correct json object. it needs to be an array or a dictionary. You should use JSONSerialization – Leo Dabus Oct 11 '17 at 18:34
  • 1
    What does your first `print(responseString)` shows? Is your post successful? – Leo Dabus Oct 11 '17 at 18:38
  • 1
    A *concrete* example (with responseString, key and iv) is needed ... – Martin R Oct 11 '17 at 18:40
  • @LeoDabus Yes it prints optional("response from server ") – techno Oct 11 '17 at 18:42
  • @MartinR Please refer http://sketchytech.blogspot.in/2016/02/resurrecting-commoncrypto-in-swift-for.html?m=1 – techno Oct 11 '17 at 18:43
  • @techno can you print your `print(postString.data(using: .utf8)!)` – Leo Dabus Oct 11 '17 at 18:45
  • 1
    @techno: No. *You* have to provide a [mcve], in the question itself. – Martin R Oct 11 '17 at 18:45
  • @LeoDabus what I'm actually trying to achieve is secure communication between client OSX Application and Server for license verification https://stackoverflow.com/q/46694385/848968 – techno Oct 11 '17 at 18:47
  • You need to make sure you are passing a valid json object – Leo Dabus Oct 11 '17 at 18:49
  • There are so many reasons why your code can fail. Perhaps the response is not valid Base64, perhaps the key is wrong, whatever. Up to now (after several requests) you haven't even shown your concrete response string. We cannot *guess* what the problem is. We need the concrete input data and the expected result. – Did you **debug** your code to check at which point the decoding fails? – Martin R Oct 11 '17 at 18:49
  • @LeoDabus But .... I don't use JSON anywhere.... Or do I ? – techno Oct 11 '17 at 18:51
  • 1
    What you send to the server is `var data="blah"` ... the key and email are not used at all. Is that your real code? – Martin R Oct 11 '17 at 18:53
  • @MartinR I'm sending like this `var data="data1=\(value1)&data2=\(value2)&data3=\(value3)"` – techno Oct 11 '17 at 18:56
  • @MartinR it's not the real code ... I will post it tomorrow... The keycode and the IV are same as the one used in the reference link ... I'm on my mobile now... – techno Oct 11 '17 at 18:57
  • 1
    Summary so far: Decrypting the (unknown) response of an unknown request with some key (which you don't provide) fails, and what you show is not the real code ... I am not sure what answer you expected. – Martin R Oct 11 '17 at 19:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156519/discussion-between-techno-and-martin-r). – techno Oct 12 '17 at 06:59
  • @MartinR Yes, I did debug my code..It returns `Failed` when the key is not valid.But when an encrypted result is returned.. the decryption as I do in the above code prints " " – techno Oct 12 '17 at 07:03
  • @MartinR Any help.. I'm still stuck...I have removed he `string(describing:)` `let unencode = responseString?.aesDecrypt(key: "123456789012asdsadasd", iv: "iv-salt-string--") print(unencode)` Still the same issue. – techno Oct 13 '17 at 06:59
  • Again: What does `print(responseString!)` show? The actual output please! – Martin R Oct 13 '17 at 07:03
  • @MartinR It prints `JDoNBXk21oJ9x15Bkv12uw==` When the string value is `abc` with `keystring=123456789012asdsadasd`and `iv=iv-salt-string--` – techno Oct 13 '17 at 07:10
  • @techno `if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {` you should return if not 200 – Leo Dabus Oct 13 '17 at 13:25
  • As @MartinR already mentioned don't use `String(describing:)` unwrap your optionals – Leo Dabus Oct 13 '17 at 13:27
  • @LeoDabus I already have unwrapped I guess `let unencode = responseString?.aesDecrypt(key: "123456789012asdsadasd", iv: "iv-salt-string--") print(unencode)` This also gives the same result. Please see my above comment... – techno Oct 13 '17 at 17:51
  • @MartinR I already have removed String(describing:) ..why is the issue happening...Is there no way to solve this – techno Oct 13 '17 at 17:52
  • @techno: The error seems to be in your PHP script. Apparently the server encrypts an *empty string* and sends that back. Check if the script works correctly. I am not an PHP expert, but: Where is `$data` defined? What response do you expect? – Martin R Oct 13 '17 at 19:25
  • @MartinR I have confirmed that the php script works fine... `printf($td);` prints the result. – techno Oct 14 '17 at 07:36
  • @techno: What I meat is: What do you expect the *decrypted* response to be? Your PHP script computes `openssl_encrypt($data, ...)` and `$data` seems to be undefined. That looks to me as if it encrypts an empty string, and that is what you get back after decrypting. – Martin R Oct 14 '17 at 07:43
  • @MartinR No I have confirmed it by giving different inputs and cross checking with SWIFT... – techno Oct 14 '17 at 07:44
  • 1
    @techno: I have verified that `"JDoNBXk21oJ9x15Bkv12uw=="` is *exactly* the result of encrypting an *empty string* with your key and iv. The error is in your PHP script, not in the Swift code. – And you did not answer my questions. Where is `$data` defined and what do you expect as the decrypted response? – Martin R Oct 14 '17 at 07:55
  • @MartinR That did the trick :) works just fine... Thanks a lot... I did not take a close look at the php code. – techno Oct 14 '17 at 10:14
  • 1
    @MartinR I will delete the question now... – techno Oct 14 '17 at 10:14
  • @MartinR I have been stuck with this for days ... can you please take a look https://stackoverflow.com/questions/46824301/detecting-face-from-an-image-and-drawing-text-on-it – techno Oct 20 '17 at 03:46
  • @LeoDabus I have opened a bounty of 100 for the question related to face detection.Could you please take a look https://stackoverflow.com/questions/46804074/nsimage-getting-resized-when-i-draw-text-on-it/ – techno Oct 20 '17 at 10:18
  • @MartinR posted your findings as an answer so this Q will stop showing up in my queries, but would prefer to see you get the bounty. – brichins Oct 20 '17 at 17:25

1 Answers1

1

Per MartinR's comment:

I have verified that "JDoNBXk21oJ9x15Bkv12uw==" is exactly the result of encrypting an empty string with your key and iv. The error is in your PHP script, not in the Swift code.

Therefore you need to resolve the error on the server.

brichins
  • 3,825
  • 2
  • 39
  • 60