AES encryption in swift











up vote
13
down vote

favorite
12












I'm trying to implement AES encryption in swift. The encryption decryption for Android and C# is working properly. I need to implement it in swift. It's current code for android and C# is followed by this.



I tried to use




  1. CryptoSwift

  2. Cross platform AES encryption


But none of it work. When I send the encrypted string on server it's not been decrypted.



Any help will be appreciated










share|improve this question
























  • Just compare output of working implementation. Standard test vectors for AES in various modes of operation are available.
    – user3703887
    Jun 7 '16 at 13:11










  • @TruthSerum I tried to compare the encrypted value but it's not matching. I don't have access to android code, so I can't debug it too. I just got this link as a reference which I had already added in question
    – Ankita Shah
    Jun 7 '16 at 13:13










  • Then look at the input parameters. You will have a 16byte plaintext block, a 16-20 bytes key (depending on AES-128, AES-256 .etc variant) and an IV initialization vector. All three need to match, for every block. You also need to make sure the padding protocol is the same between versions.
    – user3703887
    Jun 7 '16 at 13:15






  • 1




    I'm getting only kCCOptionPKCS7Padding. How can I set it to PKCS5 padding with CBC mode? Checked but didn't found any solution for it too
    – Ankita Shah
    Jun 7 '16 at 13:18






  • 1




    You need to use the same padding mode to decrypt and encrypt. If your API does not support it, you will have to implement it yourself. This might involve unpadding the wrong format, then repadding to the correct format. Again, you will find test vectors to verify that it's working correctly at every stage.
    – user3703887
    Jun 7 '16 at 13:22















up vote
13
down vote

favorite
12












I'm trying to implement AES encryption in swift. The encryption decryption for Android and C# is working properly. I need to implement it in swift. It's current code for android and C# is followed by this.



I tried to use




  1. CryptoSwift

  2. Cross platform AES encryption


But none of it work. When I send the encrypted string on server it's not been decrypted.



Any help will be appreciated










share|improve this question
























  • Just compare output of working implementation. Standard test vectors for AES in various modes of operation are available.
    – user3703887
    Jun 7 '16 at 13:11










  • @TruthSerum I tried to compare the encrypted value but it's not matching. I don't have access to android code, so I can't debug it too. I just got this link as a reference which I had already added in question
    – Ankita Shah
    Jun 7 '16 at 13:13










  • Then look at the input parameters. You will have a 16byte plaintext block, a 16-20 bytes key (depending on AES-128, AES-256 .etc variant) and an IV initialization vector. All three need to match, for every block. You also need to make sure the padding protocol is the same between versions.
    – user3703887
    Jun 7 '16 at 13:15






  • 1




    I'm getting only kCCOptionPKCS7Padding. How can I set it to PKCS5 padding with CBC mode? Checked but didn't found any solution for it too
    – Ankita Shah
    Jun 7 '16 at 13:18






  • 1




    You need to use the same padding mode to decrypt and encrypt. If your API does not support it, you will have to implement it yourself. This might involve unpadding the wrong format, then repadding to the correct format. Again, you will find test vectors to verify that it's working correctly at every stage.
    – user3703887
    Jun 7 '16 at 13:22













up vote
13
down vote

favorite
12









up vote
13
down vote

favorite
12






12





I'm trying to implement AES encryption in swift. The encryption decryption for Android and C# is working properly. I need to implement it in swift. It's current code for android and C# is followed by this.



I tried to use




  1. CryptoSwift

  2. Cross platform AES encryption


But none of it work. When I send the encrypted string on server it's not been decrypted.



Any help will be appreciated










share|improve this question















I'm trying to implement AES encryption in swift. The encryption decryption for Android and C# is working properly. I need to implement it in swift. It's current code for android and C# is followed by this.



I tried to use




  1. CryptoSwift

  2. Cross platform AES encryption


But none of it work. When I send the encrypted string on server it's not been decrypted.



Any help will be appreciated







ios swift cryptography aes commoncrypto






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 23 '17 at 11:47









Community

11




11










asked Jun 7 '16 at 13:09









Ankita Shah

1,13121137




1,13121137












  • Just compare output of working implementation. Standard test vectors for AES in various modes of operation are available.
    – user3703887
    Jun 7 '16 at 13:11










  • @TruthSerum I tried to compare the encrypted value but it's not matching. I don't have access to android code, so I can't debug it too. I just got this link as a reference which I had already added in question
    – Ankita Shah
    Jun 7 '16 at 13:13










  • Then look at the input parameters. You will have a 16byte plaintext block, a 16-20 bytes key (depending on AES-128, AES-256 .etc variant) and an IV initialization vector. All three need to match, for every block. You also need to make sure the padding protocol is the same between versions.
    – user3703887
    Jun 7 '16 at 13:15






  • 1




    I'm getting only kCCOptionPKCS7Padding. How can I set it to PKCS5 padding with CBC mode? Checked but didn't found any solution for it too
    – Ankita Shah
    Jun 7 '16 at 13:18






  • 1




    You need to use the same padding mode to decrypt and encrypt. If your API does not support it, you will have to implement it yourself. This might involve unpadding the wrong format, then repadding to the correct format. Again, you will find test vectors to verify that it's working correctly at every stage.
    – user3703887
    Jun 7 '16 at 13:22


















  • Just compare output of working implementation. Standard test vectors for AES in various modes of operation are available.
    – user3703887
    Jun 7 '16 at 13:11










  • @TruthSerum I tried to compare the encrypted value but it's not matching. I don't have access to android code, so I can't debug it too. I just got this link as a reference which I had already added in question
    – Ankita Shah
    Jun 7 '16 at 13:13










  • Then look at the input parameters. You will have a 16byte plaintext block, a 16-20 bytes key (depending on AES-128, AES-256 .etc variant) and an IV initialization vector. All three need to match, for every block. You also need to make sure the padding protocol is the same between versions.
    – user3703887
    Jun 7 '16 at 13:15






  • 1




    I'm getting only kCCOptionPKCS7Padding. How can I set it to PKCS5 padding with CBC mode? Checked but didn't found any solution for it too
    – Ankita Shah
    Jun 7 '16 at 13:18






  • 1




    You need to use the same padding mode to decrypt and encrypt. If your API does not support it, you will have to implement it yourself. This might involve unpadding the wrong format, then repadding to the correct format. Again, you will find test vectors to verify that it's working correctly at every stage.
    – user3703887
    Jun 7 '16 at 13:22
















Just compare output of working implementation. Standard test vectors for AES in various modes of operation are available.
– user3703887
Jun 7 '16 at 13:11




Just compare output of working implementation. Standard test vectors for AES in various modes of operation are available.
– user3703887
Jun 7 '16 at 13:11












@TruthSerum I tried to compare the encrypted value but it's not matching. I don't have access to android code, so I can't debug it too. I just got this link as a reference which I had already added in question
– Ankita Shah
Jun 7 '16 at 13:13




@TruthSerum I tried to compare the encrypted value but it's not matching. I don't have access to android code, so I can't debug it too. I just got this link as a reference which I had already added in question
– Ankita Shah
Jun 7 '16 at 13:13












Then look at the input parameters. You will have a 16byte plaintext block, a 16-20 bytes key (depending on AES-128, AES-256 .etc variant) and an IV initialization vector. All three need to match, for every block. You also need to make sure the padding protocol is the same between versions.
– user3703887
Jun 7 '16 at 13:15




Then look at the input parameters. You will have a 16byte plaintext block, a 16-20 bytes key (depending on AES-128, AES-256 .etc variant) and an IV initialization vector. All three need to match, for every block. You also need to make sure the padding protocol is the same between versions.
– user3703887
Jun 7 '16 at 13:15




1




1




I'm getting only kCCOptionPKCS7Padding. How can I set it to PKCS5 padding with CBC mode? Checked but didn't found any solution for it too
– Ankita Shah
Jun 7 '16 at 13:18




I'm getting only kCCOptionPKCS7Padding. How can I set it to PKCS5 padding with CBC mode? Checked but didn't found any solution for it too
– Ankita Shah
Jun 7 '16 at 13:18




1




1




You need to use the same padding mode to decrypt and encrypt. If your API does not support it, you will have to implement it yourself. This might involve unpadding the wrong format, then repadding to the correct format. Again, you will find test vectors to verify that it's working correctly at every stage.
– user3703887
Jun 7 '16 at 13:22




You need to use the same padding mode to decrypt and encrypt. If your API does not support it, you will have to implement it yourself. This might involve unpadding the wrong format, then repadding to the correct format. Again, you will find test vectors to verify that it's working correctly at every stage.
– user3703887
Jun 7 '16 at 13:22












6 Answers
6






active

oldest

votes

















up vote
27
down vote



accepted










Be sure to use the same parameters which seem to be AES with CBC mode with iv, PKCS5Padding (actually PKCS#7) padding and a 16-byte (128-bit) key.



PKCS#5 padding and PKCS#7 padding are essentially the same, sometimes for historic reasons PKCS#5 padding is specified for use with AES but the actual padding is PKCS#7.



Make sure the encodings of the key, iv and encrypted data all match. Hex dump them on both platforms to ensure they are identical. Encryption functions are not difficult to use, if all the input parameters are correct the output will be correct.



To make this more secure the iv should be random bytes and prepended to the encrypted data for use during decryption.



The Cross platform AES encryption uses a 256-bit key so will not work as-is.



Example:




Swift 2




// operation: kCCEncrypt or kCCDecrypt
func testCrypt(data data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
let cryptLength = size_t(data.count+kCCBlockSizeAES128)
var cryptData = [UInt8](count:cryptLength, repeatedValue:0)

let keyLength = size_t(kCCKeySizeAES128)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

var numBytesEncrypted :size_t = 0

let cryptStatus = CCCrypt(CCOperation(operation),
algoritm,
options,
keyData, keyLength,
ivData,
data, data.count,
&cryptData, cryptLength,
&numBytesEncrypted)

if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeRange(numBytesEncrypted..<cryptData.count)

} else {
print("Error: (cryptStatus)")
}

return cryptData;
}

let message = "Don´t try to read this text. Top Secret Stuff"
let messageData = Array(message.utf8)
let keyData = Array("12345678901234567890123456789012".utf8)
let ivData = Array("abcdefghijklmnop".utf8)
let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)!
let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)!
var decrypted = String(bytes:decryptedData, encoding:NSUTF8StringEncoding)!

print("message: (message)");
print("messageData: (NSData(bytes:messageData, length:messageData.count))");
print("keyData: (NSData(bytes:keyData, length:keyData.count))");
print("ivData: (NSData(bytes:ivData, length:ivData.count))");
print("encryptedData: (NSData(bytes:encryptedData, length:encryptedData.count))");
print("decryptedData: (NSData(bytes:decryptedData, length:decryptedData.count))");
print("decrypted: (String(bytes:decryptedData,encoding:NSUTF8StringEncoding)!)");


Output:




message: Don´t try to read this text. Top Secret Stuff
messageData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
keyData: 31323334 35363738 39303132 33343536 37383930 31323334 35363738 39303132
ivData: 61626364 65666768 696a6b6c 6d6e6f70
encryptedData: b1b6dc17 62eaf3f8 baa1cb87 21ddc35c dee803ed fb320020 85794848 21206943 a85feb5b c8ee58fc d6fb664b 96b81114
decryptedData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
decrypted: Don´t try to read this text. Top Secret Stuff



Swift 3 with [UInt8] type




func testCrypt(data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
let cryptLength = size_t(data.count+kCCBlockSizeAES128)
var cryptData = [UInt8](repeating:0, count:cryptLength)

let keyLength = size_t(kCCKeySizeAES128)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

var numBytesEncrypted :size_t = 0

let cryptStatus = CCCrypt(CCOperation(operation),
algoritm,
options,
keyData, keyLength,
ivData,
data, data.count,
&cryptData, cryptLength,
&numBytesEncrypted)

if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

} else {
print("Error: (cryptStatus)")
}

return cryptData;
}



Swift 3 & 4 with Data type




func testCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
let cryptLength = size_t(data.count + kCCBlockSizeAES128)
var cryptData = Data(count:cryptLength)

let keyLength = size_t(kCCKeySizeAES128)
let options = CCOptions(kCCOptionPKCS7Padding)


var numBytesEncrypted :size_t = 0

let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
data.withUnsafeBytes {dataBytes in
ivData.withUnsafeBytes {ivBytes in
keyData.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(operation),
CCAlgorithm(kCCAlgorithmAES),
options,
keyBytes, keyLength,
ivBytes,
dataBytes, data.count,
cryptBytes, cryptLength,
&numBytesEncrypted)
}
}
}
}

if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

} else {
print("Error: (cryptStatus)")
}

return cryptData;
}

let message = "Don´t try to read this text. Top Secret Stuff"
let messageData = message.data(using:String.Encoding.utf8)!
let keyData = "12345678901234567890123456789012".data(using:String.Encoding.utf8)!
let ivData = "abcdefghijklmnop".data(using:String.Encoding.utf8)!

let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)
let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)
var decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!


Example from sunsetted documentation section:



AES encryption in CBC mode with a random IV (Swift 3+)



The iv is prefixed to the encrypted data



aesCBC128Encrypt will create a random IV and prefixed to the encrypted code.
aesCBC128Decrypt will use the prefixed IV during decryption.



Inputs are the data and key are Data objects. If an encoded form such as Base64 if required convert to and/or from in the calling method.



The key should be exactly 128-bits (16-bytes), 192-bits (24-bytes) or 256-bits (32-bytes) in length. If another key size is used an error will be thrown.



PKCS#7 padding is set by default.



This example requires Common Crypto

It is necessary to have a bridging header to the project:
#import <CommonCrypto/CommonCrypto.h>

Add the Security.framework to the project.



This is example, not production code.



enum AESError: Error {
case KeyError((String, Int))
case IVError((String, Int))
case CryptorError((String, Int))
}

// The iv is prefixed to the encrypted data
func aesCBCEncrypt(data:Data, keyData:Data) throws -> Data {
let keyLength = keyData.count
let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
if (validKeyLengths.contains(keyLength) == false) {
throw AESError.KeyError(("Invalid key length", keyLength))
}

let ivSize = kCCBlockSizeAES128;
let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128)
var cryptData = Data(count:cryptLength)

let status = cryptData.withUnsafeMutableBytes {ivBytes in
SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes)
}
if (status != 0) {
throw AESError.IVError(("IV generation failed", Int(status)))
}

var numBytesEncrypted :size_t = 0
let options = CCOptions(kCCOptionPKCS7Padding)

let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
data.withUnsafeBytes {dataBytes in
keyData.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(kCCEncrypt),
CCAlgorithm(kCCAlgorithmAES),
options,
keyBytes, keyLength,
cryptBytes,
dataBytes, data.count,
cryptBytes+kCCBlockSizeAES128, cryptLength,
&numBytesEncrypted)
}
}
}

if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.count = numBytesEncrypted + ivSize
}
else {
throw AESError.CryptorError(("Encryption failed", Int(cryptStatus)))
}

return cryptData;
}

// The iv is prefixed to the encrypted data
func aesCBCDecrypt(data:Data, keyData:Data) throws -> Data? {
let keyLength = keyData.count
let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
if (validKeyLengths.contains(keyLength) == false) {
throw AESError.KeyError(("Invalid key length", keyLength))
}

let ivSize = kCCBlockSizeAES128;
let clearLength = size_t(data.count - ivSize)
var clearData = Data(count:clearLength)

var numBytesDecrypted :size_t = 0
let options = CCOptions(kCCOptionPKCS7Padding)

let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in
data.withUnsafeBytes {dataBytes in
keyData.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES128),
options,
keyBytes, keyLength,
dataBytes,
dataBytes+kCCBlockSizeAES128, clearLength,
cryptBytes, clearLength,
&numBytesDecrypted)
}
}
}

if UInt32(cryptStatus) == UInt32(kCCSuccess) {
clearData.count = numBytesDecrypted
}
else {
throw AESError.CryptorError(("Decryption failed", Int(cryptStatus)))
}

return clearData;
}


Example usage:



let clearData = "clearData0123456".data(using:String.Encoding.utf8)!
let keyData = "keyData890123456".data(using:String.Encoding.utf8)!
print("clearData: (clearData as NSData)")
print("keyData: (keyData as NSData)")

var cryptData :Data?
do {
cryptData = try aesCBCEncrypt(data:clearData, keyData:keyData)
print("cryptData: (cryptData! as NSData)")
}
catch (let status) {
print("Error aesCBCEncrypt: (status)")
}

let decryptData :Data?
do {
let decryptData = try aesCBCDecrypt(data:cryptData!, keyData:keyData)
print("decryptData: (decryptData! as NSData)")
}
catch (let status) {
print("Error aesCBCDecrypt: (status)")
}


Example Output:



clearData:   <636c6561 72446174 61303132 33343536>
keyData: <6b657944 61746138 39303132 33343536>
cryptData: <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0>
decryptData: <636c6561 72446174 61303132 33343536>


Notes:

One typical problem with CBC mode example code is that it leaves the creation and sharing of the random IV to the user. This example includes generation of the IV, prefixed the encrypted data and uses the prefixed IV during decryption. This frees the casual user from the details that are necessary for CBC mode.



For security the encrypted data also should have authentication, this example code does not provide that in order to be small and allow better interoperability for other platforms.



Also missing is key derivation of the key from a password, it is suggested that PBKDF2 be used is text passwords are used as keying material.



For robust production ready multi-platform encryption code see RNCryptor.






share|improve this answer























  • Implementation contains ECB mode. How can I set CBC mode?
    – Ankita Shah
    Jun 8 '16 at 4:35










  • Added example code to answer.
    – zaph
    Jun 8 '16 at 12:36






  • 1




    please help. I want the encryption in String. I tried to convert [UInt8] to String but it's returning nil. Please help. How can I get encrypted string value
    – Ankita Shah
    Jun 20 '16 at 11:27






  • 1




    Not all bytes are representable as printable characters and most are not representable as unicode characters. Encryption is a data operation and the output is essentially random 8-bit bytes and as such will not be representable directly as string characters. The answer is to convert the encrypted output to a different encoding, Base64 and hexadecimal are the usual encodings and on decryption to convert the string representation back to [Uint8].
    – zaph
    Jun 20 '16 at 11:39








  • 1




    Its also working in swift 4. Tanks...
    – Deepak Tagadiya
    Jan 8 at 14:54


















up vote
2
down vote













my two cents:



swift 4 / xcode 9 extension for Data:



extension Data{

func aesEncrypt( keyData: Data, ivData: Data, operation: Int) -> Data {
let dataLength = self.count
let cryptLength = size_t(dataLength + kCCBlockSizeAES128)
var cryptData = Data(count:cryptLength)

let keyLength = size_t(kCCKeySizeAES128)
let options = CCOptions(kCCOptionPKCS7Padding)


var numBytesEncrypted :size_t = 0

let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
self.withUnsafeBytes {dataBytes in
ivData.withUnsafeBytes {ivBytes in
keyData.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(operation),
CCAlgorithm(kCCAlgorithmAES),
options,
keyBytes, keyLength,
ivBytes,
dataBytes, dataLength,
cryptBytes, cryptLength,
&numBytesEncrypted)
}
}
}
}

if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

} else {
print("Error: (cryptStatus)")
}

return cryptData;
}

}




func testAES() -> Bool {

let message = "secret message"
let key = "key890123456"
let ivString = "abcdefghijklmnop" // 16 bytes for AES128

let messageData = message.data(using:String.Encoding.utf8)!
let keyData = key.data(using: .utf8)!
let ivData = ivString.data(using: .utf8)!

let encryptedData = messageData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCEncrypt)
let decryptedData = encryptedData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCDecrypt)
let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!

return message == decrypted

}





share|improve this answer

















  • 1




    1. The key should be the correct length, 16-bytes given kCCKeySizeAES128 in the code. Relying on undocumented key extension should not be done. 2. This is one example from the accepted answer wrapped in an extension with out attribution. But it is pleasing that @ingconti saw fit to use my code. 😄
    – zaph
    Oct 30 '17 at 20:58




















up vote
1
down vote













I have used CryptoSwift.



First I have install cryptoSwift in the pod file. Then in my view controller I have import CryptoSwift.



Here is the code that I have used:



let value = "xyzzy".  // This is the value that we want to encrypt
let key = "abc". // This is the key

let EncryptedValue = try! value.aesEncrypt(key: key)
let DecryptedValue = try! EncryptedValue.aesDecrypt(key: key)


Then, using String extension:



extension String {

func aesEncrypt(key: String) throws -> String {

var result = ""

do {

let key: [UInt8] = Array(key.utf8) as [UInt8]
let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
let encrypted = try aes.encrypt(Array(self.utf8))

result = encrypted.toBase64()!

print("AES Encryption Result: (result)")

} catch {

print("Error: (error)")
}

return result
}

func aesDecrypt(key: String) throws -> String {

var result = ""

do {

let encrypted = self
let key: [UInt8] = Array(key.utf8) as [UInt8]
let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
let decrypted = try aes.decrypt(Array(base64: encrypted))

result = String(data: Data(decrypted), encoding: .utf8) ?? ""

print("AES Decryption Result: (result)")

} catch {

print("Error: (error)")
}

return result
}
}


In this I have not used iv and encrypted.toBase64() to encrypt like result = encrypted.toBase64()! in place of result = encrypted.toStringHex()! in encryption



and similar in decryption let decrypted = try aes.decrypt(Array(base64: encrypted)) in place of let decrypted = try aes.decrypt(Array(Hex: encrypted))






share|improve this answer























  • which version you are using?
    – anand prakash
    Aug 9 at 12:33










  • Getting Error as : "Type 'BlockMode' has no member 'ECB' "
    – jeet.chanchawat
    Nov 19 at 10:38










  • How did you managed to do without iV ?
    – jeet.chanchawat
    Nov 19 at 10:44










  • let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) in this case there is no need of iv. and check you have install pod 'CryptoSwift' in your pod or not. And if you done this then import CryptoSwift in your file. This thing work for me..
    – Ayush Bansal
    Nov 26 at 11:54


















up vote
0
down vote













Found a nice library named RNCryptor implemented in swift language for AES encryption/ decryption.



Installation can be done with Cocoapods or Carthage.
Here is the sample code for encryption and decryption.



// Encryption
let data = "sample data string".data(using: String.Encoding.utf8)
let password = "Secret password"
let encryptedData = RNCryptor.encrypt(data: data, withPassword: password)

// Decryption
do {
let originalData = try RNCryptor.decrypt(data: encryptedData, withPassword: password)
// ...
} catch {
print(error)
}





share|improve this answer





















  • nice lib, but why to add a LOT of files for simple job.. :)
    – ingconti
    Feb 2 at 17:36


















up vote
0
down vote













For anyone who cannot transform array of bytes to a String



String(data: Data(decrypted), encoding: .utf8)


This is my example string extension



extension String {

func decryptAES(key: String, iv: String) -> String {
do {
let encrypted = self
let key = Array(key.utf8)
let iv = Array(iv.utf8)
let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
let decrypted = try aes.decrypt(Array(hex: encrypted))
return String(data: Data(decrypted), encoding: .utf8) ?? ""
} catch {
return "Error: (error)"
}
}
}





share|improve this answer




























    up vote
    0
    down vote













    Swift 4.2



    I refactored @ingconti 's code.



    import Foundation
    import CommonCrypto

    struct AES {

    // MARK: - Value
    // MARK: Private
    private let key: Data
    private let iv: Data


    // MARK: - Initialzier
    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
    }


    // MARK: - Function
    // MARK: Public
    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(bytes: decryptedData, encoding: .utf8)
    }

    func crypt(data: Data?, option: CCOperation) -> Data? {
    guard let data = data else { return nil }

    let cryptLength = [UInt8](repeating: 0, count: data.count + kCCBlockSizeAES128).count
    var cryptData = Data(count: cryptLength)

    let keyLength = [UInt8](repeating: 0, count: kCCBlockSizeAES128).count
    let options = CCOptions(kCCOptionPKCS7Padding)

    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), options, keyBytes, keyLength, ivBytes, dataBytes, data.count, cryptBytes, cryptLength, &bytesLength)
    }
    }
    }
    }

    guard UInt32(status) == UInt32(kCCSuccess) else {
    debugPrint("Error: Failed to crypt data. Status (status)")
    return nil
    }

    cryptData.removeSubrange(bytesLength..<cryptData.count)
    return cryptData
    }
    }




    Use like this



    let password = "UserPassword1!"
    let key128 = "1234567890123456" // 16 bytes for AES128
    let key256 = "12345678901234561234567890123456" // 32 bytes for AES256
    let iv = "abcdefghijklmnop" // 16 bytes for AES128

    let aes128 = AES(key: key128, iv: iv)
    let aes256 = AES(key: key256, iv: iv)

    let encryptedPassword128 = aes128?.encrypt(string: password)
    aes128?.decrypt(data: encryptedPassword128)

    let encryptedPassword256 = aes256?.encrypt(string: password)
    aes256?.decrypt(data: encryptedPassword256)




    Results



    enter image description here






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f37680361%2faes-encryption-in-swift%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      27
      down vote



      accepted










      Be sure to use the same parameters which seem to be AES with CBC mode with iv, PKCS5Padding (actually PKCS#7) padding and a 16-byte (128-bit) key.



      PKCS#5 padding and PKCS#7 padding are essentially the same, sometimes for historic reasons PKCS#5 padding is specified for use with AES but the actual padding is PKCS#7.



      Make sure the encodings of the key, iv and encrypted data all match. Hex dump them on both platforms to ensure they are identical. Encryption functions are not difficult to use, if all the input parameters are correct the output will be correct.



      To make this more secure the iv should be random bytes and prepended to the encrypted data for use during decryption.



      The Cross platform AES encryption uses a 256-bit key so will not work as-is.



      Example:




      Swift 2




      // operation: kCCEncrypt or kCCDecrypt
      func testCrypt(data data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](count:cryptLength, repeatedValue:0)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeRange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = Array(message.utf8)
      let keyData = Array("12345678901234567890123456789012".utf8)
      let ivData = Array("abcdefghijklmnop".utf8)
      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)!
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)!
      var decrypted = String(bytes:decryptedData, encoding:NSUTF8StringEncoding)!

      print("message: (message)");
      print("messageData: (NSData(bytes:messageData, length:messageData.count))");
      print("keyData: (NSData(bytes:keyData, length:keyData.count))");
      print("ivData: (NSData(bytes:ivData, length:ivData.count))");
      print("encryptedData: (NSData(bytes:encryptedData, length:encryptedData.count))");
      print("decryptedData: (NSData(bytes:decryptedData, length:decryptedData.count))");
      print("decrypted: (String(bytes:decryptedData,encoding:NSUTF8StringEncoding)!)");


      Output:




      message: Don´t try to read this text. Top Secret Stuff
      messageData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      keyData: 31323334 35363738 39303132 33343536 37383930 31323334 35363738 39303132
      ivData: 61626364 65666768 696a6b6c 6d6e6f70
      encryptedData: b1b6dc17 62eaf3f8 baa1cb87 21ddc35c dee803ed fb320020 85794848 21206943 a85feb5b c8ee58fc d6fb664b 96b81114
      decryptedData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      decrypted: Don´t try to read this text. Top Secret Stuff



      Swift 3 with [UInt8] type




      func testCrypt(data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](repeating:0, count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }



      Swift 3 & 4 with Data type




      func testCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
      let cryptLength = size_t(data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, data.count,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = "12345678901234567890123456789012".data(using:String.Encoding.utf8)!
      let ivData = "abcdefghijklmnop".data(using:String.Encoding.utf8)!

      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      var decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!


      Example from sunsetted documentation section:



      AES encryption in CBC mode with a random IV (Swift 3+)



      The iv is prefixed to the encrypted data



      aesCBC128Encrypt will create a random IV and prefixed to the encrypted code.
      aesCBC128Decrypt will use the prefixed IV during decryption.



      Inputs are the data and key are Data objects. If an encoded form such as Base64 if required convert to and/or from in the calling method.



      The key should be exactly 128-bits (16-bytes), 192-bits (24-bytes) or 256-bits (32-bytes) in length. If another key size is used an error will be thrown.



      PKCS#7 padding is set by default.



      This example requires Common Crypto

      It is necessary to have a bridging header to the project:
      #import <CommonCrypto/CommonCrypto.h>

      Add the Security.framework to the project.



      This is example, not production code.



      enum AESError: Error {
      case KeyError((String, Int))
      case IVError((String, Int))
      case CryptorError((String, Int))
      }

      // The iv is prefixed to the encrypted data
      func aesCBCEncrypt(data:Data, keyData:Data) throws -> Data {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let status = cryptData.withUnsafeMutableBytes {ivBytes in
      SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes)
      }
      if (status != 0) {
      throw AESError.IVError(("IV generation failed", Int(status)))
      }

      var numBytesEncrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCEncrypt),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      cryptBytes,
      dataBytes, data.count,
      cryptBytes+kCCBlockSizeAES128, cryptLength,
      &numBytesEncrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.count = numBytesEncrypted + ivSize
      }
      else {
      throw AESError.CryptorError(("Encryption failed", Int(cryptStatus)))
      }

      return cryptData;
      }

      // The iv is prefixed to the encrypted data
      func aesCBCDecrypt(data:Data, keyData:Data) throws -> Data? {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let clearLength = size_t(data.count - ivSize)
      var clearData = Data(count:clearLength)

      var numBytesDecrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCDecrypt),
      CCAlgorithm(kCCAlgorithmAES128),
      options,
      keyBytes, keyLength,
      dataBytes,
      dataBytes+kCCBlockSizeAES128, clearLength,
      cryptBytes, clearLength,
      &numBytesDecrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      clearData.count = numBytesDecrypted
      }
      else {
      throw AESError.CryptorError(("Decryption failed", Int(cryptStatus)))
      }

      return clearData;
      }


      Example usage:



      let clearData = "clearData0123456".data(using:String.Encoding.utf8)!
      let keyData = "keyData890123456".data(using:String.Encoding.utf8)!
      print("clearData: (clearData as NSData)")
      print("keyData: (keyData as NSData)")

      var cryptData :Data?
      do {
      cryptData = try aesCBCEncrypt(data:clearData, keyData:keyData)
      print("cryptData: (cryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCEncrypt: (status)")
      }

      let decryptData :Data?
      do {
      let decryptData = try aesCBCDecrypt(data:cryptData!, keyData:keyData)
      print("decryptData: (decryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCDecrypt: (status)")
      }


      Example Output:



      clearData:   <636c6561 72446174 61303132 33343536>
      keyData: <6b657944 61746138 39303132 33343536>
      cryptData: <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0>
      decryptData: <636c6561 72446174 61303132 33343536>


      Notes:

      One typical problem with CBC mode example code is that it leaves the creation and sharing of the random IV to the user. This example includes generation of the IV, prefixed the encrypted data and uses the prefixed IV during decryption. This frees the casual user from the details that are necessary for CBC mode.



      For security the encrypted data also should have authentication, this example code does not provide that in order to be small and allow better interoperability for other platforms.



      Also missing is key derivation of the key from a password, it is suggested that PBKDF2 be used is text passwords are used as keying material.



      For robust production ready multi-platform encryption code see RNCryptor.






      share|improve this answer























      • Implementation contains ECB mode. How can I set CBC mode?
        – Ankita Shah
        Jun 8 '16 at 4:35










      • Added example code to answer.
        – zaph
        Jun 8 '16 at 12:36






      • 1




        please help. I want the encryption in String. I tried to convert [UInt8] to String but it's returning nil. Please help. How can I get encrypted string value
        – Ankita Shah
        Jun 20 '16 at 11:27






      • 1




        Not all bytes are representable as printable characters and most are not representable as unicode characters. Encryption is a data operation and the output is essentially random 8-bit bytes and as such will not be representable directly as string characters. The answer is to convert the encrypted output to a different encoding, Base64 and hexadecimal are the usual encodings and on decryption to convert the string representation back to [Uint8].
        – zaph
        Jun 20 '16 at 11:39








      • 1




        Its also working in swift 4. Tanks...
        – Deepak Tagadiya
        Jan 8 at 14:54















      up vote
      27
      down vote



      accepted










      Be sure to use the same parameters which seem to be AES with CBC mode with iv, PKCS5Padding (actually PKCS#7) padding and a 16-byte (128-bit) key.



      PKCS#5 padding and PKCS#7 padding are essentially the same, sometimes for historic reasons PKCS#5 padding is specified for use with AES but the actual padding is PKCS#7.



      Make sure the encodings of the key, iv and encrypted data all match. Hex dump them on both platforms to ensure they are identical. Encryption functions are not difficult to use, if all the input parameters are correct the output will be correct.



      To make this more secure the iv should be random bytes and prepended to the encrypted data for use during decryption.



      The Cross platform AES encryption uses a 256-bit key so will not work as-is.



      Example:




      Swift 2




      // operation: kCCEncrypt or kCCDecrypt
      func testCrypt(data data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](count:cryptLength, repeatedValue:0)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeRange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = Array(message.utf8)
      let keyData = Array("12345678901234567890123456789012".utf8)
      let ivData = Array("abcdefghijklmnop".utf8)
      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)!
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)!
      var decrypted = String(bytes:decryptedData, encoding:NSUTF8StringEncoding)!

      print("message: (message)");
      print("messageData: (NSData(bytes:messageData, length:messageData.count))");
      print("keyData: (NSData(bytes:keyData, length:keyData.count))");
      print("ivData: (NSData(bytes:ivData, length:ivData.count))");
      print("encryptedData: (NSData(bytes:encryptedData, length:encryptedData.count))");
      print("decryptedData: (NSData(bytes:decryptedData, length:decryptedData.count))");
      print("decrypted: (String(bytes:decryptedData,encoding:NSUTF8StringEncoding)!)");


      Output:




      message: Don´t try to read this text. Top Secret Stuff
      messageData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      keyData: 31323334 35363738 39303132 33343536 37383930 31323334 35363738 39303132
      ivData: 61626364 65666768 696a6b6c 6d6e6f70
      encryptedData: b1b6dc17 62eaf3f8 baa1cb87 21ddc35c dee803ed fb320020 85794848 21206943 a85feb5b c8ee58fc d6fb664b 96b81114
      decryptedData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      decrypted: Don´t try to read this text. Top Secret Stuff



      Swift 3 with [UInt8] type




      func testCrypt(data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](repeating:0, count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }



      Swift 3 & 4 with Data type




      func testCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
      let cryptLength = size_t(data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, data.count,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = "12345678901234567890123456789012".data(using:String.Encoding.utf8)!
      let ivData = "abcdefghijklmnop".data(using:String.Encoding.utf8)!

      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      var decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!


      Example from sunsetted documentation section:



      AES encryption in CBC mode with a random IV (Swift 3+)



      The iv is prefixed to the encrypted data



      aesCBC128Encrypt will create a random IV and prefixed to the encrypted code.
      aesCBC128Decrypt will use the prefixed IV during decryption.



      Inputs are the data and key are Data objects. If an encoded form such as Base64 if required convert to and/or from in the calling method.



      The key should be exactly 128-bits (16-bytes), 192-bits (24-bytes) or 256-bits (32-bytes) in length. If another key size is used an error will be thrown.



      PKCS#7 padding is set by default.



      This example requires Common Crypto

      It is necessary to have a bridging header to the project:
      #import <CommonCrypto/CommonCrypto.h>

      Add the Security.framework to the project.



      This is example, not production code.



      enum AESError: Error {
      case KeyError((String, Int))
      case IVError((String, Int))
      case CryptorError((String, Int))
      }

      // The iv is prefixed to the encrypted data
      func aesCBCEncrypt(data:Data, keyData:Data) throws -> Data {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let status = cryptData.withUnsafeMutableBytes {ivBytes in
      SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes)
      }
      if (status != 0) {
      throw AESError.IVError(("IV generation failed", Int(status)))
      }

      var numBytesEncrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCEncrypt),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      cryptBytes,
      dataBytes, data.count,
      cryptBytes+kCCBlockSizeAES128, cryptLength,
      &numBytesEncrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.count = numBytesEncrypted + ivSize
      }
      else {
      throw AESError.CryptorError(("Encryption failed", Int(cryptStatus)))
      }

      return cryptData;
      }

      // The iv is prefixed to the encrypted data
      func aesCBCDecrypt(data:Data, keyData:Data) throws -> Data? {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let clearLength = size_t(data.count - ivSize)
      var clearData = Data(count:clearLength)

      var numBytesDecrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCDecrypt),
      CCAlgorithm(kCCAlgorithmAES128),
      options,
      keyBytes, keyLength,
      dataBytes,
      dataBytes+kCCBlockSizeAES128, clearLength,
      cryptBytes, clearLength,
      &numBytesDecrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      clearData.count = numBytesDecrypted
      }
      else {
      throw AESError.CryptorError(("Decryption failed", Int(cryptStatus)))
      }

      return clearData;
      }


      Example usage:



      let clearData = "clearData0123456".data(using:String.Encoding.utf8)!
      let keyData = "keyData890123456".data(using:String.Encoding.utf8)!
      print("clearData: (clearData as NSData)")
      print("keyData: (keyData as NSData)")

      var cryptData :Data?
      do {
      cryptData = try aesCBCEncrypt(data:clearData, keyData:keyData)
      print("cryptData: (cryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCEncrypt: (status)")
      }

      let decryptData :Data?
      do {
      let decryptData = try aesCBCDecrypt(data:cryptData!, keyData:keyData)
      print("decryptData: (decryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCDecrypt: (status)")
      }


      Example Output:



      clearData:   <636c6561 72446174 61303132 33343536>
      keyData: <6b657944 61746138 39303132 33343536>
      cryptData: <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0>
      decryptData: <636c6561 72446174 61303132 33343536>


      Notes:

      One typical problem with CBC mode example code is that it leaves the creation and sharing of the random IV to the user. This example includes generation of the IV, prefixed the encrypted data and uses the prefixed IV during decryption. This frees the casual user from the details that are necessary for CBC mode.



      For security the encrypted data also should have authentication, this example code does not provide that in order to be small and allow better interoperability for other platforms.



      Also missing is key derivation of the key from a password, it is suggested that PBKDF2 be used is text passwords are used as keying material.



      For robust production ready multi-platform encryption code see RNCryptor.






      share|improve this answer























      • Implementation contains ECB mode. How can I set CBC mode?
        – Ankita Shah
        Jun 8 '16 at 4:35










      • Added example code to answer.
        – zaph
        Jun 8 '16 at 12:36






      • 1




        please help. I want the encryption in String. I tried to convert [UInt8] to String but it's returning nil. Please help. How can I get encrypted string value
        – Ankita Shah
        Jun 20 '16 at 11:27






      • 1




        Not all bytes are representable as printable characters and most are not representable as unicode characters. Encryption is a data operation and the output is essentially random 8-bit bytes and as such will not be representable directly as string characters. The answer is to convert the encrypted output to a different encoding, Base64 and hexadecimal are the usual encodings and on decryption to convert the string representation back to [Uint8].
        – zaph
        Jun 20 '16 at 11:39








      • 1




        Its also working in swift 4. Tanks...
        – Deepak Tagadiya
        Jan 8 at 14:54













      up vote
      27
      down vote



      accepted







      up vote
      27
      down vote



      accepted






      Be sure to use the same parameters which seem to be AES with CBC mode with iv, PKCS5Padding (actually PKCS#7) padding and a 16-byte (128-bit) key.



      PKCS#5 padding and PKCS#7 padding are essentially the same, sometimes for historic reasons PKCS#5 padding is specified for use with AES but the actual padding is PKCS#7.



      Make sure the encodings of the key, iv and encrypted data all match. Hex dump them on both platforms to ensure they are identical. Encryption functions are not difficult to use, if all the input parameters are correct the output will be correct.



      To make this more secure the iv should be random bytes and prepended to the encrypted data for use during decryption.



      The Cross platform AES encryption uses a 256-bit key so will not work as-is.



      Example:




      Swift 2




      // operation: kCCEncrypt or kCCDecrypt
      func testCrypt(data data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](count:cryptLength, repeatedValue:0)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeRange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = Array(message.utf8)
      let keyData = Array("12345678901234567890123456789012".utf8)
      let ivData = Array("abcdefghijklmnop".utf8)
      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)!
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)!
      var decrypted = String(bytes:decryptedData, encoding:NSUTF8StringEncoding)!

      print("message: (message)");
      print("messageData: (NSData(bytes:messageData, length:messageData.count))");
      print("keyData: (NSData(bytes:keyData, length:keyData.count))");
      print("ivData: (NSData(bytes:ivData, length:ivData.count))");
      print("encryptedData: (NSData(bytes:encryptedData, length:encryptedData.count))");
      print("decryptedData: (NSData(bytes:decryptedData, length:decryptedData.count))");
      print("decrypted: (String(bytes:decryptedData,encoding:NSUTF8StringEncoding)!)");


      Output:




      message: Don´t try to read this text. Top Secret Stuff
      messageData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      keyData: 31323334 35363738 39303132 33343536 37383930 31323334 35363738 39303132
      ivData: 61626364 65666768 696a6b6c 6d6e6f70
      encryptedData: b1b6dc17 62eaf3f8 baa1cb87 21ddc35c dee803ed fb320020 85794848 21206943 a85feb5b c8ee58fc d6fb664b 96b81114
      decryptedData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      decrypted: Don´t try to read this text. Top Secret Stuff



      Swift 3 with [UInt8] type




      func testCrypt(data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](repeating:0, count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }



      Swift 3 & 4 with Data type




      func testCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
      let cryptLength = size_t(data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, data.count,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = "12345678901234567890123456789012".data(using:String.Encoding.utf8)!
      let ivData = "abcdefghijklmnop".data(using:String.Encoding.utf8)!

      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      var decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!


      Example from sunsetted documentation section:



      AES encryption in CBC mode with a random IV (Swift 3+)



      The iv is prefixed to the encrypted data



      aesCBC128Encrypt will create a random IV and prefixed to the encrypted code.
      aesCBC128Decrypt will use the prefixed IV during decryption.



      Inputs are the data and key are Data objects. If an encoded form such as Base64 if required convert to and/or from in the calling method.



      The key should be exactly 128-bits (16-bytes), 192-bits (24-bytes) or 256-bits (32-bytes) in length. If another key size is used an error will be thrown.



      PKCS#7 padding is set by default.



      This example requires Common Crypto

      It is necessary to have a bridging header to the project:
      #import <CommonCrypto/CommonCrypto.h>

      Add the Security.framework to the project.



      This is example, not production code.



      enum AESError: Error {
      case KeyError((String, Int))
      case IVError((String, Int))
      case CryptorError((String, Int))
      }

      // The iv is prefixed to the encrypted data
      func aesCBCEncrypt(data:Data, keyData:Data) throws -> Data {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let status = cryptData.withUnsafeMutableBytes {ivBytes in
      SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes)
      }
      if (status != 0) {
      throw AESError.IVError(("IV generation failed", Int(status)))
      }

      var numBytesEncrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCEncrypt),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      cryptBytes,
      dataBytes, data.count,
      cryptBytes+kCCBlockSizeAES128, cryptLength,
      &numBytesEncrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.count = numBytesEncrypted + ivSize
      }
      else {
      throw AESError.CryptorError(("Encryption failed", Int(cryptStatus)))
      }

      return cryptData;
      }

      // The iv is prefixed to the encrypted data
      func aesCBCDecrypt(data:Data, keyData:Data) throws -> Data? {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let clearLength = size_t(data.count - ivSize)
      var clearData = Data(count:clearLength)

      var numBytesDecrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCDecrypt),
      CCAlgorithm(kCCAlgorithmAES128),
      options,
      keyBytes, keyLength,
      dataBytes,
      dataBytes+kCCBlockSizeAES128, clearLength,
      cryptBytes, clearLength,
      &numBytesDecrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      clearData.count = numBytesDecrypted
      }
      else {
      throw AESError.CryptorError(("Decryption failed", Int(cryptStatus)))
      }

      return clearData;
      }


      Example usage:



      let clearData = "clearData0123456".data(using:String.Encoding.utf8)!
      let keyData = "keyData890123456".data(using:String.Encoding.utf8)!
      print("clearData: (clearData as NSData)")
      print("keyData: (keyData as NSData)")

      var cryptData :Data?
      do {
      cryptData = try aesCBCEncrypt(data:clearData, keyData:keyData)
      print("cryptData: (cryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCEncrypt: (status)")
      }

      let decryptData :Data?
      do {
      let decryptData = try aesCBCDecrypt(data:cryptData!, keyData:keyData)
      print("decryptData: (decryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCDecrypt: (status)")
      }


      Example Output:



      clearData:   <636c6561 72446174 61303132 33343536>
      keyData: <6b657944 61746138 39303132 33343536>
      cryptData: <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0>
      decryptData: <636c6561 72446174 61303132 33343536>


      Notes:

      One typical problem with CBC mode example code is that it leaves the creation and sharing of the random IV to the user. This example includes generation of the IV, prefixed the encrypted data and uses the prefixed IV during decryption. This frees the casual user from the details that are necessary for CBC mode.



      For security the encrypted data also should have authentication, this example code does not provide that in order to be small and allow better interoperability for other platforms.



      Also missing is key derivation of the key from a password, it is suggested that PBKDF2 be used is text passwords are used as keying material.



      For robust production ready multi-platform encryption code see RNCryptor.






      share|improve this answer














      Be sure to use the same parameters which seem to be AES with CBC mode with iv, PKCS5Padding (actually PKCS#7) padding and a 16-byte (128-bit) key.



      PKCS#5 padding and PKCS#7 padding are essentially the same, sometimes for historic reasons PKCS#5 padding is specified for use with AES but the actual padding is PKCS#7.



      Make sure the encodings of the key, iv and encrypted data all match. Hex dump them on both platforms to ensure they are identical. Encryption functions are not difficult to use, if all the input parameters are correct the output will be correct.



      To make this more secure the iv should be random bytes and prepended to the encrypted data for use during decryption.



      The Cross platform AES encryption uses a 256-bit key so will not work as-is.



      Example:




      Swift 2




      // operation: kCCEncrypt or kCCDecrypt
      func testCrypt(data data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](count:cryptLength, repeatedValue:0)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeRange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = Array(message.utf8)
      let keyData = Array("12345678901234567890123456789012".utf8)
      let ivData = Array("abcdefghijklmnop".utf8)
      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)!
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)!
      var decrypted = String(bytes:decryptedData, encoding:NSUTF8StringEncoding)!

      print("message: (message)");
      print("messageData: (NSData(bytes:messageData, length:messageData.count))");
      print("keyData: (NSData(bytes:keyData, length:keyData.count))");
      print("ivData: (NSData(bytes:ivData, length:ivData.count))");
      print("encryptedData: (NSData(bytes:encryptedData, length:encryptedData.count))");
      print("decryptedData: (NSData(bytes:decryptedData, length:decryptedData.count))");
      print("decrypted: (String(bytes:decryptedData,encoding:NSUTF8StringEncoding)!)");


      Output:




      message: Don´t try to read this text. Top Secret Stuff
      messageData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      keyData: 31323334 35363738 39303132 33343536 37383930 31323334 35363738 39303132
      ivData: 61626364 65666768 696a6b6c 6d6e6f70
      encryptedData: b1b6dc17 62eaf3f8 baa1cb87 21ddc35c dee803ed fb320020 85794848 21206943 a85feb5b c8ee58fc d6fb664b 96b81114
      decryptedData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
      decrypted: Don´t try to read this text. Top Secret Stuff



      Swift 3 with [UInt8] type




      func testCrypt(data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
      let cryptLength = size_t(data.count+kCCBlockSizeAES128)
      var cryptData = [UInt8](repeating:0, count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
      let options: CCOptions = UInt32(kCCOptionPKCS7Padding)

      var numBytesEncrypted :size_t = 0

      let cryptStatus = CCCrypt(CCOperation(operation),
      algoritm,
      options,
      keyData, keyLength,
      ivData,
      data, data.count,
      &cryptData, cryptLength,
      &numBytesEncrypted)

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }



      Swift 3 & 4 with Data type




      func testCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
      let cryptLength = size_t(data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, data.count,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      let message = "Don´t try to read this text. Top Secret Stuff"
      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = "12345678901234567890123456789012".data(using:String.Encoding.utf8)!
      let ivData = "abcdefghijklmnop".data(using:String.Encoding.utf8)!

      let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = testCrypt(data:encryptedData, keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      var decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!


      Example from sunsetted documentation section:



      AES encryption in CBC mode with a random IV (Swift 3+)



      The iv is prefixed to the encrypted data



      aesCBC128Encrypt will create a random IV and prefixed to the encrypted code.
      aesCBC128Decrypt will use the prefixed IV during decryption.



      Inputs are the data and key are Data objects. If an encoded form such as Base64 if required convert to and/or from in the calling method.



      The key should be exactly 128-bits (16-bytes), 192-bits (24-bytes) or 256-bits (32-bytes) in length. If another key size is used an error will be thrown.



      PKCS#7 padding is set by default.



      This example requires Common Crypto

      It is necessary to have a bridging header to the project:
      #import <CommonCrypto/CommonCrypto.h>

      Add the Security.framework to the project.



      This is example, not production code.



      enum AESError: Error {
      case KeyError((String, Int))
      case IVError((String, Int))
      case CryptorError((String, Int))
      }

      // The iv is prefixed to the encrypted data
      func aesCBCEncrypt(data:Data, keyData:Data) throws -> Data {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let status = cryptData.withUnsafeMutableBytes {ivBytes in
      SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes)
      }
      if (status != 0) {
      throw AESError.IVError(("IV generation failed", Int(status)))
      }

      var numBytesEncrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCEncrypt),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      cryptBytes,
      dataBytes, data.count,
      cryptBytes+kCCBlockSizeAES128, cryptLength,
      &numBytesEncrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.count = numBytesEncrypted + ivSize
      }
      else {
      throw AESError.CryptorError(("Encryption failed", Int(cryptStatus)))
      }

      return cryptData;
      }

      // The iv is prefixed to the encrypted data
      func aesCBCDecrypt(data:Data, keyData:Data) throws -> Data? {
      let keyLength = keyData.count
      let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
      if (validKeyLengths.contains(keyLength) == false) {
      throw AESError.KeyError(("Invalid key length", keyLength))
      }

      let ivSize = kCCBlockSizeAES128;
      let clearLength = size_t(data.count - ivSize)
      var clearData = Data(count:clearLength)

      var numBytesDecrypted :size_t = 0
      let options = CCOptions(kCCOptionPKCS7Padding)

      let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in
      data.withUnsafeBytes {dataBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(kCCDecrypt),
      CCAlgorithm(kCCAlgorithmAES128),
      options,
      keyBytes, keyLength,
      dataBytes,
      dataBytes+kCCBlockSizeAES128, clearLength,
      cryptBytes, clearLength,
      &numBytesDecrypted)
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      clearData.count = numBytesDecrypted
      }
      else {
      throw AESError.CryptorError(("Decryption failed", Int(cryptStatus)))
      }

      return clearData;
      }


      Example usage:



      let clearData = "clearData0123456".data(using:String.Encoding.utf8)!
      let keyData = "keyData890123456".data(using:String.Encoding.utf8)!
      print("clearData: (clearData as NSData)")
      print("keyData: (keyData as NSData)")

      var cryptData :Data?
      do {
      cryptData = try aesCBCEncrypt(data:clearData, keyData:keyData)
      print("cryptData: (cryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCEncrypt: (status)")
      }

      let decryptData :Data?
      do {
      let decryptData = try aesCBCDecrypt(data:cryptData!, keyData:keyData)
      print("decryptData: (decryptData! as NSData)")
      }
      catch (let status) {
      print("Error aesCBCDecrypt: (status)")
      }


      Example Output:



      clearData:   <636c6561 72446174 61303132 33343536>
      keyData: <6b657944 61746138 39303132 33343536>
      cryptData: <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0>
      decryptData: <636c6561 72446174 61303132 33343536>


      Notes:

      One typical problem with CBC mode example code is that it leaves the creation and sharing of the random IV to the user. This example includes generation of the IV, prefixed the encrypted data and uses the prefixed IV during decryption. This frees the casual user from the details that are necessary for CBC mode.



      For security the encrypted data also should have authentication, this example code does not provide that in order to be small and allow better interoperability for other platforms.



      Also missing is key derivation of the key from a password, it is suggested that PBKDF2 be used is text passwords are used as keying material.



      For robust production ready multi-platform encryption code see RNCryptor.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 8 at 20:34

























      answered Jun 7 '16 at 13:58









      zaph

      97.2k18150193




      97.2k18150193












      • Implementation contains ECB mode. How can I set CBC mode?
        – Ankita Shah
        Jun 8 '16 at 4:35










      • Added example code to answer.
        – zaph
        Jun 8 '16 at 12:36






      • 1




        please help. I want the encryption in String. I tried to convert [UInt8] to String but it's returning nil. Please help. How can I get encrypted string value
        – Ankita Shah
        Jun 20 '16 at 11:27






      • 1




        Not all bytes are representable as printable characters and most are not representable as unicode characters. Encryption is a data operation and the output is essentially random 8-bit bytes and as such will not be representable directly as string characters. The answer is to convert the encrypted output to a different encoding, Base64 and hexadecimal are the usual encodings and on decryption to convert the string representation back to [Uint8].
        – zaph
        Jun 20 '16 at 11:39








      • 1




        Its also working in swift 4. Tanks...
        – Deepak Tagadiya
        Jan 8 at 14:54


















      • Implementation contains ECB mode. How can I set CBC mode?
        – Ankita Shah
        Jun 8 '16 at 4:35










      • Added example code to answer.
        – zaph
        Jun 8 '16 at 12:36






      • 1




        please help. I want the encryption in String. I tried to convert [UInt8] to String but it's returning nil. Please help. How can I get encrypted string value
        – Ankita Shah
        Jun 20 '16 at 11:27






      • 1




        Not all bytes are representable as printable characters and most are not representable as unicode characters. Encryption is a data operation and the output is essentially random 8-bit bytes and as such will not be representable directly as string characters. The answer is to convert the encrypted output to a different encoding, Base64 and hexadecimal are the usual encodings and on decryption to convert the string representation back to [Uint8].
        – zaph
        Jun 20 '16 at 11:39








      • 1




        Its also working in swift 4. Tanks...
        – Deepak Tagadiya
        Jan 8 at 14:54
















      Implementation contains ECB mode. How can I set CBC mode?
      – Ankita Shah
      Jun 8 '16 at 4:35




      Implementation contains ECB mode. How can I set CBC mode?
      – Ankita Shah
      Jun 8 '16 at 4:35












      Added example code to answer.
      – zaph
      Jun 8 '16 at 12:36




      Added example code to answer.
      – zaph
      Jun 8 '16 at 12:36




      1




      1




      please help. I want the encryption in String. I tried to convert [UInt8] to String but it's returning nil. Please help. How can I get encrypted string value
      – Ankita Shah
      Jun 20 '16 at 11:27




      please help. I want the encryption in String. I tried to convert [UInt8] to String but it's returning nil. Please help. How can I get encrypted string value
      – Ankita Shah
      Jun 20 '16 at 11:27




      1




      1




      Not all bytes are representable as printable characters and most are not representable as unicode characters. Encryption is a data operation and the output is essentially random 8-bit bytes and as such will not be representable directly as string characters. The answer is to convert the encrypted output to a different encoding, Base64 and hexadecimal are the usual encodings and on decryption to convert the string representation back to [Uint8].
      – zaph
      Jun 20 '16 at 11:39






      Not all bytes are representable as printable characters and most are not representable as unicode characters. Encryption is a data operation and the output is essentially random 8-bit bytes and as such will not be representable directly as string characters. The answer is to convert the encrypted output to a different encoding, Base64 and hexadecimal are the usual encodings and on decryption to convert the string representation back to [Uint8].
      – zaph
      Jun 20 '16 at 11:39






      1




      1




      Its also working in swift 4. Tanks...
      – Deepak Tagadiya
      Jan 8 at 14:54




      Its also working in swift 4. Tanks...
      – Deepak Tagadiya
      Jan 8 at 14:54












      up vote
      2
      down vote













      my two cents:



      swift 4 / xcode 9 extension for Data:



      extension Data{

      func aesEncrypt( keyData: Data, ivData: Data, operation: Int) -> Data {
      let dataLength = self.count
      let cryptLength = size_t(dataLength + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      self.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, dataLength,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      }




      func testAES() -> Bool {

      let message = "secret message"
      let key = "key890123456"
      let ivString = "abcdefghijklmnop" // 16 bytes for AES128

      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = key.data(using: .utf8)!
      let ivData = ivString.data(using: .utf8)!

      let encryptedData = messageData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = encryptedData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!

      return message == decrypted

      }





      share|improve this answer

















      • 1




        1. The key should be the correct length, 16-bytes given kCCKeySizeAES128 in the code. Relying on undocumented key extension should not be done. 2. This is one example from the accepted answer wrapped in an extension with out attribution. But it is pleasing that @ingconti saw fit to use my code. 😄
        – zaph
        Oct 30 '17 at 20:58

















      up vote
      2
      down vote













      my two cents:



      swift 4 / xcode 9 extension for Data:



      extension Data{

      func aesEncrypt( keyData: Data, ivData: Data, operation: Int) -> Data {
      let dataLength = self.count
      let cryptLength = size_t(dataLength + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      self.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, dataLength,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      }




      func testAES() -> Bool {

      let message = "secret message"
      let key = "key890123456"
      let ivString = "abcdefghijklmnop" // 16 bytes for AES128

      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = key.data(using: .utf8)!
      let ivData = ivString.data(using: .utf8)!

      let encryptedData = messageData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = encryptedData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!

      return message == decrypted

      }





      share|improve this answer

















      • 1




        1. The key should be the correct length, 16-bytes given kCCKeySizeAES128 in the code. Relying on undocumented key extension should not be done. 2. This is one example from the accepted answer wrapped in an extension with out attribution. But it is pleasing that @ingconti saw fit to use my code. 😄
        – zaph
        Oct 30 '17 at 20:58















      up vote
      2
      down vote










      up vote
      2
      down vote









      my two cents:



      swift 4 / xcode 9 extension for Data:



      extension Data{

      func aesEncrypt( keyData: Data, ivData: Data, operation: Int) -> Data {
      let dataLength = self.count
      let cryptLength = size_t(dataLength + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      self.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, dataLength,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      }




      func testAES() -> Bool {

      let message = "secret message"
      let key = "key890123456"
      let ivString = "abcdefghijklmnop" // 16 bytes for AES128

      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = key.data(using: .utf8)!
      let ivData = ivString.data(using: .utf8)!

      let encryptedData = messageData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = encryptedData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!

      return message == decrypted

      }





      share|improve this answer












      my two cents:



      swift 4 / xcode 9 extension for Data:



      extension Data{

      func aesEncrypt( keyData: Data, ivData: Data, operation: Int) -> Data {
      let dataLength = self.count
      let cryptLength = size_t(dataLength + kCCBlockSizeAES128)
      var cryptData = Data(count:cryptLength)

      let keyLength = size_t(kCCKeySizeAES128)
      let options = CCOptions(kCCOptionPKCS7Padding)


      var numBytesEncrypted :size_t = 0

      let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
      self.withUnsafeBytes {dataBytes in
      ivData.withUnsafeBytes {ivBytes in
      keyData.withUnsafeBytes {keyBytes in
      CCCrypt(CCOperation(operation),
      CCAlgorithm(kCCAlgorithmAES),
      options,
      keyBytes, keyLength,
      ivBytes,
      dataBytes, dataLength,
      cryptBytes, cryptLength,
      &numBytesEncrypted)
      }
      }
      }
      }

      if UInt32(cryptStatus) == UInt32(kCCSuccess) {
      cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)

      } else {
      print("Error: (cryptStatus)")
      }

      return cryptData;
      }

      }




      func testAES() -> Bool {

      let message = "secret message"
      let key = "key890123456"
      let ivString = "abcdefghijklmnop" // 16 bytes for AES128

      let messageData = message.data(using:String.Encoding.utf8)!
      let keyData = key.data(using: .utf8)!
      let ivData = ivString.data(using: .utf8)!

      let encryptedData = messageData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCEncrypt)
      let decryptedData = encryptedData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCDecrypt)
      let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!

      return message == decrypted

      }






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Oct 30 '17 at 20:37









      ingconti

      5,60413226




      5,60413226








      • 1




        1. The key should be the correct length, 16-bytes given kCCKeySizeAES128 in the code. Relying on undocumented key extension should not be done. 2. This is one example from the accepted answer wrapped in an extension with out attribution. But it is pleasing that @ingconti saw fit to use my code. 😄
        – zaph
        Oct 30 '17 at 20:58
















      • 1




        1. The key should be the correct length, 16-bytes given kCCKeySizeAES128 in the code. Relying on undocumented key extension should not be done. 2. This is one example from the accepted answer wrapped in an extension with out attribution. But it is pleasing that @ingconti saw fit to use my code. 😄
        – zaph
        Oct 30 '17 at 20:58










      1




      1




      1. The key should be the correct length, 16-bytes given kCCKeySizeAES128 in the code. Relying on undocumented key extension should not be done. 2. This is one example from the accepted answer wrapped in an extension with out attribution. But it is pleasing that @ingconti saw fit to use my code. 😄
      – zaph
      Oct 30 '17 at 20:58






      1. The key should be the correct length, 16-bytes given kCCKeySizeAES128 in the code. Relying on undocumented key extension should not be done. 2. This is one example from the accepted answer wrapped in an extension with out attribution. But it is pleasing that @ingconti saw fit to use my code. 😄
      – zaph
      Oct 30 '17 at 20:58












      up vote
      1
      down vote













      I have used CryptoSwift.



      First I have install cryptoSwift in the pod file. Then in my view controller I have import CryptoSwift.



      Here is the code that I have used:



      let value = "xyzzy".  // This is the value that we want to encrypt
      let key = "abc". // This is the key

      let EncryptedValue = try! value.aesEncrypt(key: key)
      let DecryptedValue = try! EncryptedValue.aesDecrypt(key: key)


      Then, using String extension:



      extension String {

      func aesEncrypt(key: String) throws -> String {

      var result = ""

      do {

      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let encrypted = try aes.encrypt(Array(self.utf8))

      result = encrypted.toBase64()!

      print("AES Encryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }

      func aesDecrypt(key: String) throws -> String {

      var result = ""

      do {

      let encrypted = self
      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let decrypted = try aes.decrypt(Array(base64: encrypted))

      result = String(data: Data(decrypted), encoding: .utf8) ?? ""

      print("AES Decryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }
      }


      In this I have not used iv and encrypted.toBase64() to encrypt like result = encrypted.toBase64()! in place of result = encrypted.toStringHex()! in encryption



      and similar in decryption let decrypted = try aes.decrypt(Array(base64: encrypted)) in place of let decrypted = try aes.decrypt(Array(Hex: encrypted))






      share|improve this answer























      • which version you are using?
        – anand prakash
        Aug 9 at 12:33










      • Getting Error as : "Type 'BlockMode' has no member 'ECB' "
        – jeet.chanchawat
        Nov 19 at 10:38










      • How did you managed to do without iV ?
        – jeet.chanchawat
        Nov 19 at 10:44










      • let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) in this case there is no need of iv. and check you have install pod 'CryptoSwift' in your pod or not. And if you done this then import CryptoSwift in your file. This thing work for me..
        – Ayush Bansal
        Nov 26 at 11:54















      up vote
      1
      down vote













      I have used CryptoSwift.



      First I have install cryptoSwift in the pod file. Then in my view controller I have import CryptoSwift.



      Here is the code that I have used:



      let value = "xyzzy".  // This is the value that we want to encrypt
      let key = "abc". // This is the key

      let EncryptedValue = try! value.aesEncrypt(key: key)
      let DecryptedValue = try! EncryptedValue.aesDecrypt(key: key)


      Then, using String extension:



      extension String {

      func aesEncrypt(key: String) throws -> String {

      var result = ""

      do {

      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let encrypted = try aes.encrypt(Array(self.utf8))

      result = encrypted.toBase64()!

      print("AES Encryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }

      func aesDecrypt(key: String) throws -> String {

      var result = ""

      do {

      let encrypted = self
      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let decrypted = try aes.decrypt(Array(base64: encrypted))

      result = String(data: Data(decrypted), encoding: .utf8) ?? ""

      print("AES Decryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }
      }


      In this I have not used iv and encrypted.toBase64() to encrypt like result = encrypted.toBase64()! in place of result = encrypted.toStringHex()! in encryption



      and similar in decryption let decrypted = try aes.decrypt(Array(base64: encrypted)) in place of let decrypted = try aes.decrypt(Array(Hex: encrypted))






      share|improve this answer























      • which version you are using?
        – anand prakash
        Aug 9 at 12:33










      • Getting Error as : "Type 'BlockMode' has no member 'ECB' "
        – jeet.chanchawat
        Nov 19 at 10:38










      • How did you managed to do without iV ?
        – jeet.chanchawat
        Nov 19 at 10:44










      • let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) in this case there is no need of iv. and check you have install pod 'CryptoSwift' in your pod or not. And if you done this then import CryptoSwift in your file. This thing work for me..
        – Ayush Bansal
        Nov 26 at 11:54













      up vote
      1
      down vote










      up vote
      1
      down vote









      I have used CryptoSwift.



      First I have install cryptoSwift in the pod file. Then in my view controller I have import CryptoSwift.



      Here is the code that I have used:



      let value = "xyzzy".  // This is the value that we want to encrypt
      let key = "abc". // This is the key

      let EncryptedValue = try! value.aesEncrypt(key: key)
      let DecryptedValue = try! EncryptedValue.aesDecrypt(key: key)


      Then, using String extension:



      extension String {

      func aesEncrypt(key: String) throws -> String {

      var result = ""

      do {

      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let encrypted = try aes.encrypt(Array(self.utf8))

      result = encrypted.toBase64()!

      print("AES Encryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }

      func aesDecrypt(key: String) throws -> String {

      var result = ""

      do {

      let encrypted = self
      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let decrypted = try aes.decrypt(Array(base64: encrypted))

      result = String(data: Data(decrypted), encoding: .utf8) ?? ""

      print("AES Decryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }
      }


      In this I have not used iv and encrypted.toBase64() to encrypt like result = encrypted.toBase64()! in place of result = encrypted.toStringHex()! in encryption



      and similar in decryption let decrypted = try aes.decrypt(Array(base64: encrypted)) in place of let decrypted = try aes.decrypt(Array(Hex: encrypted))






      share|improve this answer














      I have used CryptoSwift.



      First I have install cryptoSwift in the pod file. Then in my view controller I have import CryptoSwift.



      Here is the code that I have used:



      let value = "xyzzy".  // This is the value that we want to encrypt
      let key = "abc". // This is the key

      let EncryptedValue = try! value.aesEncrypt(key: key)
      let DecryptedValue = try! EncryptedValue.aesDecrypt(key: key)


      Then, using String extension:



      extension String {

      func aesEncrypt(key: String) throws -> String {

      var result = ""

      do {

      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let encrypted = try aes.encrypt(Array(self.utf8))

      result = encrypted.toBase64()!

      print("AES Encryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }

      func aesDecrypt(key: String) throws -> String {

      var result = ""

      do {

      let encrypted = self
      let key: [UInt8] = Array(key.utf8) as [UInt8]
      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
      let decrypted = try aes.decrypt(Array(base64: encrypted))

      result = String(data: Data(decrypted), encoding: .utf8) ?? ""

      print("AES Decryption Result: (result)")

      } catch {

      print("Error: (error)")
      }

      return result
      }
      }


      In this I have not used iv and encrypted.toBase64() to encrypt like result = encrypted.toBase64()! in place of result = encrypted.toStringHex()! in encryption



      and similar in decryption let decrypted = try aes.decrypt(Array(base64: encrypted)) in place of let decrypted = try aes.decrypt(Array(Hex: encrypted))







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Oct 4 at 19:18









      aguilarpgc

      1,0241220




      1,0241220










      answered Aug 9 at 9:39









      Ayush Bansal

      386




      386












      • which version you are using?
        – anand prakash
        Aug 9 at 12:33










      • Getting Error as : "Type 'BlockMode' has no member 'ECB' "
        – jeet.chanchawat
        Nov 19 at 10:38










      • How did you managed to do without iV ?
        – jeet.chanchawat
        Nov 19 at 10:44










      • let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) in this case there is no need of iv. and check you have install pod 'CryptoSwift' in your pod or not. And if you done this then import CryptoSwift in your file. This thing work for me..
        – Ayush Bansal
        Nov 26 at 11:54


















      • which version you are using?
        – anand prakash
        Aug 9 at 12:33










      • Getting Error as : "Type 'BlockMode' has no member 'ECB' "
        – jeet.chanchawat
        Nov 19 at 10:38










      • How did you managed to do without iV ?
        – jeet.chanchawat
        Nov 19 at 10:44










      • let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) in this case there is no need of iv. and check you have install pod 'CryptoSwift' in your pod or not. And if you done this then import CryptoSwift in your file. This thing work for me..
        – Ayush Bansal
        Nov 26 at 11:54
















      which version you are using?
      – anand prakash
      Aug 9 at 12:33




      which version you are using?
      – anand prakash
      Aug 9 at 12:33












      Getting Error as : "Type 'BlockMode' has no member 'ECB' "
      – jeet.chanchawat
      Nov 19 at 10:38




      Getting Error as : "Type 'BlockMode' has no member 'ECB' "
      – jeet.chanchawat
      Nov 19 at 10:38












      How did you managed to do without iV ?
      – jeet.chanchawat
      Nov 19 at 10:44




      How did you managed to do without iV ?
      – jeet.chanchawat
      Nov 19 at 10:44












      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) in this case there is no need of iv. and check you have install pod 'CryptoSwift' in your pod or not. And if you done this then import CryptoSwift in your file. This thing work for me..
      – Ayush Bansal
      Nov 26 at 11:54




      let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) in this case there is no need of iv. and check you have install pod 'CryptoSwift' in your pod or not. And if you done this then import CryptoSwift in your file. This thing work for me..
      – Ayush Bansal
      Nov 26 at 11:54










      up vote
      0
      down vote













      Found a nice library named RNCryptor implemented in swift language for AES encryption/ decryption.



      Installation can be done with Cocoapods or Carthage.
      Here is the sample code for encryption and decryption.



      // Encryption
      let data = "sample data string".data(using: String.Encoding.utf8)
      let password = "Secret password"
      let encryptedData = RNCryptor.encrypt(data: data, withPassword: password)

      // Decryption
      do {
      let originalData = try RNCryptor.decrypt(data: encryptedData, withPassword: password)
      // ...
      } catch {
      print(error)
      }





      share|improve this answer





















      • nice lib, but why to add a LOT of files for simple job.. :)
        – ingconti
        Feb 2 at 17:36















      up vote
      0
      down vote













      Found a nice library named RNCryptor implemented in swift language for AES encryption/ decryption.



      Installation can be done with Cocoapods or Carthage.
      Here is the sample code for encryption and decryption.



      // Encryption
      let data = "sample data string".data(using: String.Encoding.utf8)
      let password = "Secret password"
      let encryptedData = RNCryptor.encrypt(data: data, withPassword: password)

      // Decryption
      do {
      let originalData = try RNCryptor.decrypt(data: encryptedData, withPassword: password)
      // ...
      } catch {
      print(error)
      }





      share|improve this answer





















      • nice lib, but why to add a LOT of files for simple job.. :)
        – ingconti
        Feb 2 at 17:36













      up vote
      0
      down vote










      up vote
      0
      down vote









      Found a nice library named RNCryptor implemented in swift language for AES encryption/ decryption.



      Installation can be done with Cocoapods or Carthage.
      Here is the sample code for encryption and decryption.



      // Encryption
      let data = "sample data string".data(using: String.Encoding.utf8)
      let password = "Secret password"
      let encryptedData = RNCryptor.encrypt(data: data, withPassword: password)

      // Decryption
      do {
      let originalData = try RNCryptor.decrypt(data: encryptedData, withPassword: password)
      // ...
      } catch {
      print(error)
      }





      share|improve this answer












      Found a nice library named RNCryptor implemented in swift language for AES encryption/ decryption.



      Installation can be done with Cocoapods or Carthage.
      Here is the sample code for encryption and decryption.



      // Encryption
      let data = "sample data string".data(using: String.Encoding.utf8)
      let password = "Secret password"
      let encryptedData = RNCryptor.encrypt(data: data, withPassword: password)

      // Decryption
      do {
      let originalData = try RNCryptor.decrypt(data: encryptedData, withPassword: password)
      // ...
      } catch {
      print(error)
      }






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Dec 19 '17 at 7:46









      Alexi

      1,0361429




      1,0361429












      • nice lib, but why to add a LOT of files for simple job.. :)
        – ingconti
        Feb 2 at 17:36


















      • nice lib, but why to add a LOT of files for simple job.. :)
        – ingconti
        Feb 2 at 17:36
















      nice lib, but why to add a LOT of files for simple job.. :)
      – ingconti
      Feb 2 at 17:36




      nice lib, but why to add a LOT of files for simple job.. :)
      – ingconti
      Feb 2 at 17:36










      up vote
      0
      down vote













      For anyone who cannot transform array of bytes to a String



      String(data: Data(decrypted), encoding: .utf8)


      This is my example string extension



      extension String {

      func decryptAES(key: String, iv: String) -> String {
      do {
      let encrypted = self
      let key = Array(key.utf8)
      let iv = Array(iv.utf8)
      let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
      let decrypted = try aes.decrypt(Array(hex: encrypted))
      return String(data: Data(decrypted), encoding: .utf8) ?? ""
      } catch {
      return "Error: (error)"
      }
      }
      }





      share|improve this answer

























        up vote
        0
        down vote













        For anyone who cannot transform array of bytes to a String



        String(data: Data(decrypted), encoding: .utf8)


        This is my example string extension



        extension String {

        func decryptAES(key: String, iv: String) -> String {
        do {
        let encrypted = self
        let key = Array(key.utf8)
        let iv = Array(iv.utf8)
        let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
        let decrypted = try aes.decrypt(Array(hex: encrypted))
        return String(data: Data(decrypted), encoding: .utf8) ?? ""
        } catch {
        return "Error: (error)"
        }
        }
        }





        share|improve this answer























          up vote
          0
          down vote










          up vote
          0
          down vote









          For anyone who cannot transform array of bytes to a String



          String(data: Data(decrypted), encoding: .utf8)


          This is my example string extension



          extension String {

          func decryptAES(key: String, iv: String) -> String {
          do {
          let encrypted = self
          let key = Array(key.utf8)
          let iv = Array(iv.utf8)
          let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
          let decrypted = try aes.decrypt(Array(hex: encrypted))
          return String(data: Data(decrypted), encoding: .utf8) ?? ""
          } catch {
          return "Error: (error)"
          }
          }
          }





          share|improve this answer












          For anyone who cannot transform array of bytes to a String



          String(data: Data(decrypted), encoding: .utf8)


          This is my example string extension



          extension String {

          func decryptAES(key: String, iv: String) -> String {
          do {
          let encrypted = self
          let key = Array(key.utf8)
          let iv = Array(iv.utf8)
          let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
          let decrypted = try aes.decrypt(Array(hex: encrypted))
          return String(data: Data(decrypted), encoding: .utf8) ?? ""
          } catch {
          return "Error: (error)"
          }
          }
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Sep 11 at 8:34









          Khemmachart Chutapetch

          413




          413






















              up vote
              0
              down vote













              Swift 4.2



              I refactored @ingconti 's code.



              import Foundation
              import CommonCrypto

              struct AES {

              // MARK: - Value
              // MARK: Private
              private let key: Data
              private let iv: Data


              // MARK: - Initialzier
              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
              }


              // MARK: - Function
              // MARK: Public
              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(bytes: decryptedData, encoding: .utf8)
              }

              func crypt(data: Data?, option: CCOperation) -> Data? {
              guard let data = data else { return nil }

              let cryptLength = [UInt8](repeating: 0, count: data.count + kCCBlockSizeAES128).count
              var cryptData = Data(count: cryptLength)

              let keyLength = [UInt8](repeating: 0, count: kCCBlockSizeAES128).count
              let options = CCOptions(kCCOptionPKCS7Padding)

              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), options, keyBytes, keyLength, ivBytes, dataBytes, data.count, cryptBytes, cryptLength, &bytesLength)
              }
              }
              }
              }

              guard UInt32(status) == UInt32(kCCSuccess) else {
              debugPrint("Error: Failed to crypt data. Status (status)")
              return nil
              }

              cryptData.removeSubrange(bytesLength..<cryptData.count)
              return cryptData
              }
              }




              Use like this



              let password = "UserPassword1!"
              let key128 = "1234567890123456" // 16 bytes for AES128
              let key256 = "12345678901234561234567890123456" // 32 bytes for AES256
              let iv = "abcdefghijklmnop" // 16 bytes for AES128

              let aes128 = AES(key: key128, iv: iv)
              let aes256 = AES(key: key256, iv: iv)

              let encryptedPassword128 = aes128?.encrypt(string: password)
              aes128?.decrypt(data: encryptedPassword128)

              let encryptedPassword256 = aes256?.encrypt(string: password)
              aes256?.decrypt(data: encryptedPassword256)




              Results



              enter image description here






              share|improve this answer



























                up vote
                0
                down vote













                Swift 4.2



                I refactored @ingconti 's code.



                import Foundation
                import CommonCrypto

                struct AES {

                // MARK: - Value
                // MARK: Private
                private let key: Data
                private let iv: Data


                // MARK: - Initialzier
                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
                }


                // MARK: - Function
                // MARK: Public
                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(bytes: decryptedData, encoding: .utf8)
                }

                func crypt(data: Data?, option: CCOperation) -> Data? {
                guard let data = data else { return nil }

                let cryptLength = [UInt8](repeating: 0, count: data.count + kCCBlockSizeAES128).count
                var cryptData = Data(count: cryptLength)

                let keyLength = [UInt8](repeating: 0, count: kCCBlockSizeAES128).count
                let options = CCOptions(kCCOptionPKCS7Padding)

                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), options, keyBytes, keyLength, ivBytes, dataBytes, data.count, cryptBytes, cryptLength, &bytesLength)
                }
                }
                }
                }

                guard UInt32(status) == UInt32(kCCSuccess) else {
                debugPrint("Error: Failed to crypt data. Status (status)")
                return nil
                }

                cryptData.removeSubrange(bytesLength..<cryptData.count)
                return cryptData
                }
                }




                Use like this



                let password = "UserPassword1!"
                let key128 = "1234567890123456" // 16 bytes for AES128
                let key256 = "12345678901234561234567890123456" // 32 bytes for AES256
                let iv = "abcdefghijklmnop" // 16 bytes for AES128

                let aes128 = AES(key: key128, iv: iv)
                let aes256 = AES(key: key256, iv: iv)

                let encryptedPassword128 = aes128?.encrypt(string: password)
                aes128?.decrypt(data: encryptedPassword128)

                let encryptedPassword256 = aes256?.encrypt(string: password)
                aes256?.decrypt(data: encryptedPassword256)




                Results



                enter image description here






                share|improve this answer

























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  Swift 4.2



                  I refactored @ingconti 's code.



                  import Foundation
                  import CommonCrypto

                  struct AES {

                  // MARK: - Value
                  // MARK: Private
                  private let key: Data
                  private let iv: Data


                  // MARK: - Initialzier
                  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
                  }


                  // MARK: - Function
                  // MARK: Public
                  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(bytes: decryptedData, encoding: .utf8)
                  }

                  func crypt(data: Data?, option: CCOperation) -> Data? {
                  guard let data = data else { return nil }

                  let cryptLength = [UInt8](repeating: 0, count: data.count + kCCBlockSizeAES128).count
                  var cryptData = Data(count: cryptLength)

                  let keyLength = [UInt8](repeating: 0, count: kCCBlockSizeAES128).count
                  let options = CCOptions(kCCOptionPKCS7Padding)

                  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), options, keyBytes, keyLength, ivBytes, dataBytes, data.count, cryptBytes, cryptLength, &bytesLength)
                  }
                  }
                  }
                  }

                  guard UInt32(status) == UInt32(kCCSuccess) else {
                  debugPrint("Error: Failed to crypt data. Status (status)")
                  return nil
                  }

                  cryptData.removeSubrange(bytesLength..<cryptData.count)
                  return cryptData
                  }
                  }




                  Use like this



                  let password = "UserPassword1!"
                  let key128 = "1234567890123456" // 16 bytes for AES128
                  let key256 = "12345678901234561234567890123456" // 32 bytes for AES256
                  let iv = "abcdefghijklmnop" // 16 bytes for AES128

                  let aes128 = AES(key: key128, iv: iv)
                  let aes256 = AES(key: key256, iv: iv)

                  let encryptedPassword128 = aes128?.encrypt(string: password)
                  aes128?.decrypt(data: encryptedPassword128)

                  let encryptedPassword256 = aes256?.encrypt(string: password)
                  aes256?.decrypt(data: encryptedPassword256)




                  Results



                  enter image description here






                  share|improve this answer














                  Swift 4.2



                  I refactored @ingconti 's code.



                  import Foundation
                  import CommonCrypto

                  struct AES {

                  // MARK: - Value
                  // MARK: Private
                  private let key: Data
                  private let iv: Data


                  // MARK: - Initialzier
                  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
                  }


                  // MARK: - Function
                  // MARK: Public
                  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(bytes: decryptedData, encoding: .utf8)
                  }

                  func crypt(data: Data?, option: CCOperation) -> Data? {
                  guard let data = data else { return nil }

                  let cryptLength = [UInt8](repeating: 0, count: data.count + kCCBlockSizeAES128).count
                  var cryptData = Data(count: cryptLength)

                  let keyLength = [UInt8](repeating: 0, count: kCCBlockSizeAES128).count
                  let options = CCOptions(kCCOptionPKCS7Padding)

                  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), options, keyBytes, keyLength, ivBytes, dataBytes, data.count, cryptBytes, cryptLength, &bytesLength)
                  }
                  }
                  }
                  }

                  guard UInt32(status) == UInt32(kCCSuccess) else {
                  debugPrint("Error: Failed to crypt data. Status (status)")
                  return nil
                  }

                  cryptData.removeSubrange(bytesLength..<cryptData.count)
                  return cryptData
                  }
                  }




                  Use like this



                  let password = "UserPassword1!"
                  let key128 = "1234567890123456" // 16 bytes for AES128
                  let key256 = "12345678901234561234567890123456" // 32 bytes for AES256
                  let iv = "abcdefghijklmnop" // 16 bytes for AES128

                  let aes128 = AES(key: key128, iv: iv)
                  let aes256 = AES(key: key256, iv: iv)

                  let encryptedPassword128 = aes128?.encrypt(string: password)
                  aes128?.decrypt(data: encryptedPassword128)

                  let encryptedPassword256 = aes256?.encrypt(string: password)
                  aes256?.decrypt(data: encryptedPassword256)




                  Results



                  enter image description here







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 29 at 4:22









                  tadija

                  1,4911223




                  1,4911223










                  answered Nov 11 at 5:08









                  Den

                  50559




                  50559






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f37680361%2faes-encryption-in-swift%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Danny Elfman

                      Lugert, Oklahoma