0

I'm making an Application with a java backend and a Swift front-end. Using a REST Api to move data. I wish to encrypt the data with AES 128 CBC. The encrypting method is working, but the decrypting method is not.

First off all, this is the Swift code for de AES encrypting and decrypting:

import Foundation
import CommonCrypto

struct AES {

private let key: Data
private let iv: Data


init?() {
    let ivProduct: String = "dkghepfowntislqn"
    let keyProduct: String = "2949382094230487"
    
    guard keyProduct.count == kCCKeySizeAES128 || keyProduct.count == kCCKeySizeAES256, let keyData = keyProduct.data(using: .utf8) else {
        debugPrint("Error: Failed to set a key.")
        return nil
    }

    guard ivProduct.count == kCCBlockSizeAES128, let ivData = ivProduct.data(using: .utf8) else {
        debugPrint("Error: Failed to set an initial vector.")
        return nil
    }


    self.key = keyData
    self.iv  = ivData
}


func encrypt(string: String) -> Data? {
    return crypt(data: string.data(using: .utf8), option: CCOperation(kCCEncrypt))
}

func decrypt(data: Data?) -> String? {
    guard let decryptedData = crypt(data: data, option: CCOperation(kCCDecrypt)) else { return nil }
    return String(bytes: decryptedData, encoding: .utf8)
}

func crypt(data: Data?, option: CCOperation) -> Data? {
    guard let data = data else { return nil }

    let cryptLength = data.count + kCCBlockSizeAES128
    var cryptData   = Data(count: cryptLength)

    let keyLength = key.count
    let options   = CCOptions(kCCOptionPKCS7Padding)

    var bytesLength = Int(0)

    let status = cryptData.withUnsafeMutableBytes { cryptBytes in
        data.withUnsafeBytes { dataBytes in
            iv.withUnsafeBytes { ivBytes in
                key.withUnsafeBytes { keyBytes in
                CCCrypt(option, CCAlgorithm(kCCAlgorithmAES), options, keyBytes.baseAddress, keyLength, ivBytes.baseAddress, dataBytes.baseAddress, data.count, cryptBytes.baseAddress, cryptLength, &bytesLength)
                }
            }
        }
    }

    guard UInt32(status) == UInt32(kCCSuccess) else {
        debugPrint("Error: Failed to crypt data. Status \(status)")
        return nil
    }

    cryptData.removeSubrange(bytesLength..<cryptData.count)
    return cryptData
}
}

The data is gathered from the REST API like so:

func getTestAllPayments(_ completion: @escaping ([Payment]) -> ()) {
  let aes128 = AES()
  if let url = URL(string: "\(localhostUrl)/payment") {
           URLSession.shared.dataTask(with: url) { data, response, error in
              if let data = data {
                  do {
                    let res = try JSONDecoder().decode([Payment].self, from: (data))
                    print(res.self)
                    completion(res)
                    return
                  } catch let error {
                     print(error)
                  }
              }
           }.resume()
        }
    }

Now for the problem. I've ran a couple of test:

first check if the encrypt and decrypt methods work together:

let aes128 = AES()
let dataEncrypt = aes128?.encrypt(string:"Hello") //Will be :lG7Bqk0nwx732eOQLAzhqQ==
let dataDecrypt = aes128?.decrypt(data:dataEncrypt) //Will be: "Hello"
print(dataDecrypt) --> //output = "Hello"

First test works like a charm. For the second test:

let aes128 = AES()
  if let url = URL(string: "\(localhostUrl)/payment") {
           URLSession.shared.dataTask(with: url) { data, response, error in
              if let data = data {

                print(String(data: data, encoding: .utf8)) //Output = lG7Bqk0nwx732eOQLAzhqQ==

                let dataDecrypt = aes128?.decrypt(data: data)
                print(dataDecrypt) --> //output = nil

This is where it goes wrong. When fetching the data with the exact same encoding string, it'll always return nil. Has it something to do with the data format that URLSession returns?

Kevin Kentie
  • 107
  • 1
  • 1
  • 6
  • 1
    Could you print `data` as hexString with https://stackoverflow.com/questions/39075043/how-to-convert-data-to-hex-string-in-swift ? Could it be that there is a "space" or other strange character? Then, if needed compare with `Data("IG7Bqk0nwx732eOQLAzhqQ==".utf8)` "hex string" – Larme Apr 09 '21 at 09:46
  • Thanks for the response! So I compared the data.hexEncodedString() and the Data("IG7Bqk0nwx732eOQLAzhqQ==".utf8). The hexString is the same for both. – Kevin Kentie Apr 09 '21 at 10:04

0 Answers0