0

I'm working on a Swift Framework, connected to my servers. Data are encrypted between the application and the PHP server in AES-256-CBC. I succeed to send data from applications to the server and get the response. But now I'd like to decrypt the response and I can't.

To decrypt the server response I use a vector (sent by the server in Base64), the source data and a key (generated application-side). When I do a base64Decode on my vector, base64 returns nil. It returns nil because my vector contains some special characters and Strings don't handle special char. The problem is, I need a string and my vector to do an AES Decrypt and get back my data.

This is my Swift 3 code :

let data = Data(base64Encoded: data)!
let decrypted = try! AES(key: key, iv: iv.base64Decoded()!, blockMode: .CBC, padding: PKCS7()).decrypt([UInt8](data))
let decryptedData = Data(decrypted)

And on the second line I get the following error:

Fatal error: unexpectedly found nil while unwrapping an Optional value


EDIT :

Precisely, this is what happened :

First I created, server-side, a random vector in PHP :

openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC"));

... and encode it in base64 because it's composed with special characters.

Now, application-side I try to decode it :

extension String {
    func base64Decoded() -> String? {
        if let data = Data(base64Encoded: self) {
            return String(data: data, encoding: .utf8)
        }
        return nil
    }
}


let myVector = iv.base64Decoded()!

But that fail, because the decoded string contain non handled characters. How can I handle them ?

Thanks for all your ideas

Community
  • 1
  • 1
RedLens834
  • 231
  • 3
  • 18
  • What exactly does `data` contain? Show the output of `print(data as NSData)`. – Martin R Jun 27 '17 at 13:35
  • `data` contain the result of AES-256-CBC of a JSON. – RedLens834 Jun 27 '17 at 13:36
  • Actually it works but only when I use a vector without special characters. But I'd like to deal with special characters... – RedLens834 Jun 27 '17 at 13:37
  • What does `iv` contain? – Martin R Jun 27 '17 at 13:40
  • It contain a random initialization vector, encoded in base 64 – RedLens834 Jun 27 '17 at 13:41
  • So which part exactly returns nil? – A self-contained example with input, actual results, and expected output would be helpful. – Martin R Jun 27 '17 at 13:42
  • It's the base64 decode on the IV who returns nil : `let decodedIV = iv.base64Decoded()!` -> `Fatal error: unexpectedly found nil while unwrapping an Optional value` – RedLens834 Jun 27 '17 at 13:45
  • That should happen only if `iv` is not valid Base64. Please provide a [mcve]. – Martin R Jun 27 '17 at 13:47
  • Here is a very similar problem: https://stackoverflow.com/questions/41485494/convert-hex-encoded-string-to-string-in-swift-3, and the solution should be the same: *Don't* try to convert the binary data to a string, but pass it as an array to `AES(key: Array, iv: Array, ..)` – Martin R Jun 28 '17 at 06:53
  • Thanks, that help me ! Put your comment in answer and I'll validate it – RedLens834 Jun 28 '17 at 12:29

1 Answers1

1

You cannot interpret arbitrary data as an UTF-8 encoded string, therefore String(data: data, encoding: .utf8) will fail in most cases.

But there is another AES initializer which takes binary data (as an array) instead of strings, making the conversion to strings obsolete:

let data = Data(base64Encoded: base64data)!
let iv = Data(base64Encoded: base64iv)!

let decrypted = try! AES(Array(data), Array(iv), ...)
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382