Waxren Waxren - 7 months ago 590
Swift Question

Swift AES encryption using CommonCrypto

I am working on an iOS app on XCode 7.1 with Swift 2.1 and I am trying to do simple encryption with AES 128 bit and PKCS7 padding using CommonCrypto library.

The code works but every time I try to cast the

NSData
object to
NSString
then to String I get a nil and the app crashes.

I debugged the app and the
NSData
object is not nil.

The error occurs when I try to unwrap the String optional.

How to resolve this issue? and convert the
NSData
object to a String correctly?
Here is my code

static func AESEncryption(phrase: String,key: String,ivKey: String,encryptOrDecrypt: Bool) -> String {

let phraseData = phrase.dataUsingEncoding(NSUTF8StringEncoding)
let ivData = ivKey.dataUsingEncoding(NSUTF8StringEncoding)
let keyData: NSData! = key.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let keyBytes = UnsafePointer<Void>(keyData.bytes)
let keyLength = size_t(kCCKeySizeAES128)
let dataLength = Int(phraseData!.length)
let dataBytes = UnsafePointer<Void>(phraseData!.bytes)
let bufferData = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)!
let bufferPointer = UnsafeMutablePointer<Void>(bufferData.mutableBytes)
let bufferLength = size_t(bufferData.length)
let ivBuffer = UnsafePointer<Void>(ivData!.bytes)
var bytesDecrypted = Int(0)

let operation = encryptOrDecrypt ? UInt32(kCCEncrypt) : UInt32(kCCDecrypt)

let algorithm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

let cryptStatus = CCCrypt(
operation,
algorithm,
options,
keyBytes,
keyLength,
ivBuffer,
dataBytes,
dataLength,
bufferPointer,
bufferLength,
&bytesDecrypted)
if Int32(cryptStatus) == Int32(kCCSuccess) {
bufferData.length = bytesDecrypted

let data = bufferData as NSData
let stringData = String(data: data,encoding: NSUTF8StringEncoding)
print("After Operation: \(stringData)")
return stringData!
} else {
print("Encryption Error: \(cryptStatus)")
}
return "";
}

Answer

The encrypted data will not be a valid UTF-8 string as it should be indistinguishable from random bits. If you need it in a string form you need to do something like base64 encode it or write out the hex values of the bytes.

NSData has a base64EncodedDataWithOptions method which should produce a String.