Search code examples
iosobjective-cswiftencryptionnsdata

Why does this AES128 Decryption take so long on iPhone?


I am decrypting an image sent from a php server. I am using the CryptoSwift library to decrypt the image, the image comes in as NSData, and after the decryption, I create an UIImage from the NSData.

But the decryption takes about 1minute and 10 seconds, which is very slow. The size of the image data:

println(imageData.length)
result: 32592

I believe that's not a big file right? This is the code I use to decrypt the image data:

let aes = AES(key: keyData, iv: ivData, blockMode: .ECB) 
let decryptedData = aes?.decrypt(encryptedSnap, removePadding: true)
let image = UIImage(data: decryptedData!)

I've tried running the process on different threads, but it gave the same result. When I am decrypting the image, the simulator uses 100% CPU, and about 21.5MB of ram.

Any help is appreciated, thanks!


Solution

  • Swift 2.0

    Here is some simple sample code encrypting and decrypting NSData with ECB mode and a 128-bit AES key.

    Test code

    let keyString = "M02cnQ51Ji97vwT4"
    let keyData = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
    
    let message = "Don´t try to read this text. Top Secret Stuff"
    let data = (message as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
    
    print("data: \(data)")
    if let encryptedData = testCrypt(data, keyData:keyData, operation:UInt32(kCCEncrypt)) {
        print("encryptedData: \(encryptedData)")
        if let decryptedData = testCrypt(encryptedData, keyData:keyData, operation:UInt32(kCCDecrypt)) {
            print("decryptedData: \(decryptedData)")
        }
    }
    

    Crypto method:

    func testCrypt(data:NSData, keyData:NSData, operation:CCOperation) -> NSData? {
        let keyBytes = UnsafePointer<UInt8>(keyData.bytes)
        print("keyLength   = \(keyData.length), keyData   = \(keyData)")
    
        let dataLength = Int(data.length)
        let dataBytes  = UnsafePointer<UInt8>(data.bytes)
        print("dataLength  = \(dataLength), data      = \(data)")
    
        let cryptData: NSMutableData! = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
        let cryptPointer = UnsafeMutablePointer<UInt8>(cryptData.mutableBytes)
        let cryptLength  = size_t(cryptData.length)
    
        let keyLength              = size_t(kCCKeySizeAES128)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
    
        var numBytesEncrypted :size_t = 0
    
        let cryptStatus = CCCrypt(operation,
            algoritm,
            options,
            keyBytes, keyLength,
            nil,
            dataBytes, dataLength,
            cryptPointer, cryptLength,
            &numBytesEncrypted)
    
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)
            print("cryptLength = \(numBytesEncrypted), cryptData = \(cryptData)")
    
        } else {
            print("Error: \(cryptStatus)")
        }
    
        return cryptData;
    }
    

    Output:

    data:                         <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>
    keyLength   = 16, keyData   = <4d303263 6e513531 4a693937 76775434>
    dataLength  = 46, data      = <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>
    
    cryptLength = 48, cryptData = <5fd86c65 6544720c 9659b43f 2e77bf8d 9c2373d9 e1042a3d ce9a19f8 2900521e c3f8075a b6866ba5 2fcd5793 bbeb8e0c>
    encryptedData:                <5fd86c65 6544720c 9659b43f 2e77bf8d 9c2373d9 e1042a3d ce9a19f8 2900521e c3f8075a b6866ba5 2fcd5793 bbeb8e0c>
    keyLength   = 16, keyData   = <4d303263 6e513531 4a693937 76775434>
    dataLength  = 48, data      = <5fd86c65 6544720c 9659b43f 2e77bf8d 9c2373d9 e1042a3d ce9a19f8 2900521e c3f8075a b6866ba5 2fcd5793 bbeb8e0c>
    
    cryptLength = 46, cryptData = <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>
    decryptedData:                <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>