AES Encrypt and Decrypt
Solution 1
I found the solution, it is a good library.
Cross platform 256bit AES encryption / decryption.
This project contains the implementation of 256 bit AES encryption which works on all the platforms (C#, iOS, Android). One of the key objective is to make AES work on all the platforms with simple implementation.
Platforms Supported: iOS , Android , Windows (C#).
https://github.com/Pakhee/Cross-platform-AES-encryption
Solution 2
CryptoSwift Example
Updated to Swift 2
import Foundation
import CryptoSwift
extension String {
func aesEncrypt(key: String, iv: String) throws -> String{
let data = self.dataUsingEncoding(NSUTF8StringEncoding)
let enc = try AES(key: key, iv: iv, blockMode:.CBC).encrypt(data!.arrayOfBytes(), padding: PKCS7())
let encData = NSData(bytes: enc, length: Int(enc.count))
let base64String: String = encData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
let result = String(base64String)
return result
}
func aesDecrypt(key: String, iv: String) throws -> String {
let data = NSData(base64EncodedString: self, options: NSDataBase64DecodingOptions(rawValue: 0))
let dec = try AES(key: key, iv: iv, blockMode:.CBC).decrypt(data!.arrayOfBytes(), padding: PKCS7())
let decData = NSData(bytes: dec, length: Int(dec.count))
let result = NSString(data: decData, encoding: NSUTF8StringEncoding)
return String(result!)
}
}
Usage:
let key = "bbC2H19lkVbQDfakxcrtNMQdd0FloLyw" // length == 32
let iv = "gqLOHUioQ0QjhuvI" // length == 16
let s = "string to encrypt"
let enc = try! s.aesEncrypt(key, iv: iv)
let dec = try! enc.aesDecrypt(key, iv: iv)
print(s) // string to encrypt
print("enc:\(enc)") // 2r0+KirTTegQfF4wI8rws0LuV8h82rHyyYz7xBpXIpM=
print("dec:\(dec)") // string to encrypt
print("\(s == dec)") // true
Make sure you have the right length of iv (16) and key (32) then you won't hit "Block size and Initialization Vector must be the same length!" error.
Solution 3
CryptoSwift Example
Updated SWIFT 4.*
func aesEncrypt() throws -> String {
let encrypted = try AES(key: KEY, iv: IV, padding: .pkcs7).encrypt([UInt8](self.data(using: .utf8)!))
return Data(encrypted).base64EncodedString()
}
func aesDecrypt() throws -> String {
guard let data = Data(base64Encoded: self) else { return "" }
let decrypted = try AES(key: KEY, iv: IV, padding: .pkcs7).decrypt([UInt8](data))
return String(bytes: decrypted, encoding: .utf8) ?? self
}
Solution 4
There is an interesting "pure-swift" Open Source library:
-
CryptoSwift: https://github.com/krzyzanowskim/CryptoSwift
It supports: AES-128, AES-192, AES-256, ChaCha20
Example with AES decrypt (got from project README.md file):
import CryptoSwift
let setup = (key: keyData, iv: ivData)
let decryptedAES = AES(setup).decrypt(encryptedData)
Solution 5
I was using CommonCrypto to generate Hash through the code of MihaelIsaev/HMAC.swift from Easy to use Swift implementation of CommonCrypto HMAC. This implementation is without using Bridging-Header, with creation of Module file.
Now to use AESEncrypt and Decrypt, I directly added the functions inside "extension String {" in HAMC.swift.
func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
data = self.dataUsingEncoding(NSUTF8StringEncoding),
cryptData = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {
let keyLength = size_t(kCCKeySizeAES128)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(options)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyData.bytes, keyLength,
iv,
data.bytes, data.length,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
let base64cryptString = cryptData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
return base64cryptString
}
else {
return nil
}
}
return nil
}
func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
data = NSData(base64EncodedString: self, options: .IgnoreUnknownCharacters),
cryptData = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {
let keyLength = size_t(kCCKeySizeAES128)
let operation: CCOperation = UInt32(kCCDecrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(options)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyData.bytes, keyLength,
iv,
data.bytes, data.length,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
let unencryptedMessage = String(data: cryptData, encoding:NSUTF8StringEncoding)
return unencryptedMessage
}
else {
return nil
}
}
return nil
}
The functions were taken from RNCryptor. It was an easy addition in the hashing functions and in one single file "HMAC.swift", without using Bridging-header. I hope this will be useful for developers in swift requiring Hashing and AES Encryption/Decryption.
Example of using the AESDecrypt as under.
let iv = "AA-salt-BBCCDD--" // should be of 16 characters.
//here we are convert nsdata to String
let encryptedString = String(data: dataFromURL, encoding: NSUTF8StringEncoding)
//now we are decrypting
if let decryptedString = encryptedString?.aesDecrypt("12345678901234567890123456789012", iv: iv) // 32 char pass key
{
// Your decryptedString
}
mehr
Updated on March 19, 2020Comments
-
mehr about 4 years
I write an application by swift, i need AES Encrypt and Decrypt functionality, i received encrypted data from another .Net solution, but i can't find something to do it.
This is my .net Encryption:
public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) { byte[] encryptedBytes = null; byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; using (MemoryStream ms = new MemoryStream()) { using (RijndaelManaged AES = new RijndaelManaged()) { AES.KeySize = 256; AES.BlockSize = 128; var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Mode = CipherMode.CBC; using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length); cs.Close(); } encryptedBytes = ms.ToArray(); } } return encryptedBytes; }
I need to decrypt function in swift.
-
Deekor over 8 yearsthis code throws an error
Block size and Initialization Vector must be the same length!
when doing the encryption. -
Admin over 8 years@Deekor I just added the usage example. iv and key need to be in the right length. 16 for iv and 32 for key.
-
Fred Faust over 8 yearsIs there a way to create the IV from the key value?
-
Thiha Aung over 8 yearsi got nil error when i encrypt that string "q3xnpwB3d3+UCW1zt6LM4ePQAVkOw/ZRF5qBB7J2YTdqlZaWSzZR+oXEAOlgkt43AoY2BhqjBltf1e7ZRNs5XIPHTOkNqgYfAPzfsGUPo+8=" Something wrong?
-
zaph about 8 yearsYep, AES encryption using CryptoSwift is 500 to 1000 times slower than Common Crypto, this is because Common Crypto utilizes the hardware encryption capabilities and CryptoSwift does not.
-
zaph about 8 yearsNote that CryptoSwift is 500 to 1000 times slower than Common Crypto.
-
Artjom B. almost 8 yearsThat's quite a bad library. a) Key and IV are padded with
null
for some reason if they don't have the right size. This is bad, because people are just gonna use that with passwords, but passwords don't have enough entropy to be used as keys! Instead keys can be derived from passwords with schemes such as PBKDF2 or Argon2. b) This library doesn't provide authentication at all. c) IV's are for some reason text-based and not binary. d) The users needs to manage the IV themselves and will most likely get it wrong. -
Shree Prakash over 7 years@yutelin Can you provide me File encryption and decryption demo using CryptoSwift . Please
-
Shree Prakash over 7 yearsCan you provide me File encryption and decryption demo using RNCryptor..Please
-
SHS over 7 years@ShreePool - You may get full code in swift 3.0 and usage of HAMC from this link stackoverflow.com/a/41465726/2641380
-
Shree Prakash over 7 yearsactually I want to solve this.stackoverflow.com/questions/41542890/…
-
Jayprakash Dubey about 7 yearsHow to get IV value?
-
Rekha.t about 7 yearsproblem in both encryption and decryption while using this library.
-
zaph almost 7 yearsIt is best to avoid using CryptoSwift, amoung other things it is 500 to 1000 times slower than Common Crypto based implementations. Apple's Common Crypto is FIPS certified and as such has been well vetted, using CryptoSwift is taking a chance on correctness and security.
-
Yaroslav Dukal almost 7 yearsI am using this for encrypting chat messages. Basically what you saying is this is not good idea? I have been using it for a while and did not notice anything bad...
-
zaph almost 7 yearsEssentially every data breach can say "I have been using it for a while and did not notice anything bad" … but then something bad happened. It's like seat belts, why bother.
-
Dinesh about 6 yearsIs there any example without an iv. If yes can you please share it here.
-
Qadir Hussain almost 6 yearsgetting this error Type 'Cipher' has no member 'AES'
-
Yaroslav Dukal over 5 years@zaph It would be nice if you could provide your recommended implementation example.
-
Yaroslav Dukal over 5 years@zaph what data breach are you talking about ? How could you decrypt encrypted string not knowing what method was it used to decrypt, KEY and IV??
-
Archy Will He 何魏奇 over 5 years@MaksimKniazev hmm what do you mean?
-
Yaroslav Dukal over 5 years@ArchyWilhes魏何 what are you referring to??
-
Ahmadreza about 5 yearsUse of unresolved identifier 'AES'; did you mean 'YES'?
-
westrada almost 5 yearsYour solution works very well but in the last line of code it's not necessary doing
Data(decrypted).bytes
sincedecrypted
is [UInt8] -
NoodleOfDeath almost 5 years@QadirHussain try just
AES
instead ofCipher.AES
. -
Alex Zavatone about 4 yearsNo, you can't just copy and paste those methods. AES isn't declared anywhere. What did you do? Add
CryptoSwift
to your project and not tell us? -
user40176 about 4 yearsJust wanted to note that this is where Voatz copy and pasted the key and IV they hardcoded into their "secure" voting platform.
-
Ravi Sharma about 4 yearswhere to get value for ivData?
-
JAnton almost 4 yearsJust what I was looking for. Thx
-
Raviteja Mathangi almost 4 yearsgetting nil value in decrypted string can you help me .. i following you're code.i have only secret key and encrypted string
-
Steven W. Klassen over 3 yearsJust found a very big error in the
CommonCrypto
version of this answer. At least, it is a problem with Swift 5.2 - perhaps it was not with Swift 4.2. The problem is that only the first character of the key seems to be significant. I can decrypt my messages with any key of the same length that begins with the same letter! The problem seems to be with theArray(key)
passed as the forth argument inCCCrypt
. If I replace it with justkey
it seems to work properly. -
Amit about 3 years@MaksimKniazev please hep here stackoverflow.com/questions/66757704/…
-
Amit about 3 years@yutelin please help here stackoverflow.com/questions/66757704/…
-
metamonkey over 2 yearsFair warning folks: CryptoSwift is not worth using. Key derivation takes too much time to be feasible. stackoverflow.com/q/68931972/5786349