breakbadjames breakbadjames - 14 days ago 10
iOS Question

CryptoSwift - Converting UInt8 array to String resolves as nil

(Xcode 8, Swift 3)

Using the CryptoSwift library, I am wanting to encrypt a string and store it in coredata, for some reason, cipherstring results as nil, despite ciphertext having 128 values:

let aes = try AES(key: pw, iv: nil, blockMode: .CBC, padding: PKCS7())
let ciphertext = try aes.encrypt(token.utf8.map({$0}))
let cipherstring = String(bytes:ciphertext, encoding: String.Encoding.utf8) // always nil


I have also tried using the data: overload of string, convering the byte array to a data object. This also results as nil.

EDIT/SOLUTION (per Rob Napier's answer)

// encode/convert to string
let aes = try AES(key: pw, iv: nil, blockMode: .CBC, padding: PKCS7())
let ciphertext = try aes.encrypt(token.utf8.map({$0}))
let cipherstring = Data(bytes: ciphertext).base64EncodedString()
// decode
let aes = try AES(key: pw, iv: nil, blockMode: .CBC, padding: PKCS7())
let cipherdata = Data(base64Encoded: cipherstring)
let ciphertext = try aes.decrypt(cipherdata!.bytes)
let token = String(bytes:ciphertext, encoding:String.Encoding.utf8)

Answer

AES encrypted data is a random bunch of bytes. If you pick a random bunch of bytes, it is very unlikely to be valid UTF-8. If you have data and you want a string, you need to encode the data somehow. The most popular way to do that is Base-64. See Data.base64EncodedString() for a tool to do that. You'll also need Data(base64Encoded:) to reconstruct your Data from the String later.

Comments