Swift AES ECB decryption

822 Views Asked by At

I'm trying to decrypt a string in swift that was encrypted by a third party using AES ECB with a 256bit key and a 128bit initialization vector.

This is my swift code:

struct AES {

    private let key: Data
    private let iv: Data

    init?(key: String, iv: String) {
        guard key.count == kCCKeySizeAES128 || key.count == kCCKeySizeAES256, let keyData = key.data(using: .utf8) else {
            debugPrint("Error: Failed to set a key.")
            return nil
        }
    
        guard iv.count == kCCBlockSizeAES128, let ivData = iv.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(decoding: decryptedData, as: UTF8.self) // LINE XY
    }

    func crypt(data: Data?, option: CCOperation) -> Data? {
        guard let data = data else { return nil }
    
        let cryptLength = data.count + key.count
        var cryptData   = Data(count: cryptLength)
    
        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), CCOptions(kCCOptionPKCS7Padding), keyBytes.baseAddress, key.count, ivBytes.baseAddress, dataBytes.baseAddress, data.count, cryptBytes.baseAddress, cryptLength, &bytesLength)
                    }
                }
            }
        }
    
        guard Int32(status) == Int32(kCCSuccess) else {
            debugPrint("Error: Failed to crypt data. Status \(status)")
            return nil
        }
    
        cryptData.removeSubrange(bytesLength..<cryptData.count)
        return cryptData
    }
}

Example secrets im using:

    let key256   = "gVkYp3s6v9y$B&E)H@MbQeThWmZq4t7w"   // 32 bytes for AES256
    let iv       = "v8y/B?E(H+MbQeTh"                   // 16 bytes for initialization vector

This snippet works:

    let content = "Hello, world!"
    
    let aes256 = AES(key: key256, iv: iv)
    let encrypted = aes256?.encrypt(string: content)
    let result = aes256?.decrypt(data: encrypted) // works fine
    
    assert(content == result, "not equal!")

Now im trying to decrypt my third party string, that was encrypted using this dart package with the same settings:

    guard let fileUrl = Bundle.main.url(forResource: "inputBase64", withExtension: "txt") else { fatalError() }
    
    let base64Content = try String(contentsOf: fileUrl, encoding: .utf8)
    let data = Data(base64Encoded: base64Content, options: .ignoreUnknownCharacters)
    let result = aes256?.decrypt(data: data) // crashes my xcode

This freezes my entire xcode window as soon as it reaches the line i marked with // LINE XY in the first code block.

What could cause this crash and are there any other solutions? Thanks!

0

There are 0 best solutions below