1

I want to encrypt and decrypt a text in Swift using an AES algorithm that should be compatible with Android and PHP encryption algorithms. So, I been trying the code from the question here, but the result prints nothing. This is the code with little modifications from the original:

    var key = "abcdefghijklmnopqrstuvwxyz012345"
    var iv = "0000000000000000"
    var plainText = "Hello World"

    let keyData: NSData! = (key as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
    let keyBytes         = UnsafePointer<UInt8>(keyData.bytes)
    let keyLength        = size_t(kCCKeySizeAES256)

    let plainData = (plainText as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
    let dataLength    = size_t(plainData.length)
    let dataBytes     = UnsafePointer<UInt8>(plainData.bytes)

    var bufferData    = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
    var bufferPointer = UnsafeMutablePointer<UInt8>(bufferData!.mutableBytes)
    let bufferLength  = size_t(bufferData!.length)

    let operation: CCOperation = UInt32(kCCEncrypt)
    let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
    let options = UInt32(kCCOptionPKCS7Padding)

    let ivData: NSData! = (iv as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
    let ivPointer = UnsafePointer<UInt8>(ivData.bytes)

    var numBytesEncrypted: UnsafeMutablePointer<Int> = nil
    var cryptStatus = CCCrypt(operation, algoritm, options, keyBytes, keyLength, ivPointer, dataBytes, dataLength, bufferPointer, bufferLength, numBytesEncrypted)

    bufferData!.length = numBytesEncrypted.hashValue
    let base64cryptString = bufferData!.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
    print(base64cryptString)

Do I miss something? Please help! If you know how to solve it or got some code that works for AES encryption & decryption I'll appreciate it.

Community
  • 1
  • 1
Sergio
  • 11
  • 4
  • I don't know the answer, but all of those unsafe mutables are a real commentary on just how far along Swift really is. I wonder if it would be far easier to just do this in Objective-C or Objective-C++ and create a bridge to Swift rather than all of this casting and unsafe pointer stuff. – David Hoelzer Apr 29 '16 at 21:34
  • 3
    There is no standard way to encode AES-encrypted data. To be compatible with other platforms, you must make sure that every choice you make is the same. Unless you understand what the above code is doing (and it is quite insecure, so I assume you don't), then it is very challenging. If you're not trying to match an existing implementation, then I suggest using a pre-built solution such as RNCryptor (https://github.com/RNCryptor). See RNCryptor for Swift, JNCryptor for Android, and RNCryptor-php for PHP. – Rob Napier Apr 29 '16 at 21:34
  • 1
    @DavidHoelzer Some of the above casting is required because CommonCrypto has been ignored during the bridging of libraries to Swift, but much of it isn't actually required anymore, and some of it was never required. This code is cut and paste from someone probably working in an early version of Swift (before NSString/String bridging), and apparently with limited understanding of Optionals. – Rob Napier Apr 29 '16 at 21:45
  • Thanks @RobNapier. Good to know. – David Hoelzer Apr 29 '16 at 22:43
  • Rather than figuring out what's wrong with your code, I'd advise using the Swift version of [RNCryptor](https://github.com/RNCryptor/RNCryptor) on its [swift](https://github.com/RNCryptor/RNCryptor/tree/swift) branch, as it is non-trivial to properly encrypt in AES256 ([See related Stack Overflow question](http://stackoverflow.com/a/9795582/504931) and [blog post](http://robnapier.net/aes-commoncrypto)). – mz2 Apr 29 '16 at 22:15

0 Answers0