Jayprakash Dubey
Jayprakash Dubey

Reputation: 36447

AES128 encryption in swift

I’ve an issue with AES-128 encryption. The encrypted string in iOS is different as compared to Android.

Below is android code :

public class Encryption {
    private static final String ALGORITHM = "AES";
    private static final String UNICODE_FORMAT = "UTF8";

    public static String encryptValue(String valueToEnc) {
        try {
            Key key = generateKey();
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.ENCRYPT_MODE, key);
            byte[] encValue = c.doFinal(valueToEnc.getBytes());
            String encryptedValue = new Base64().encode(encValue);
            String urlEncodeddata = URLEncoder.encode(encryptedValue, "UTF-8");
            return urlEncodeddata;
        } catch (Exception e) {

        }
        return valueToEnc;
    }

    private static Key generateKey() throws Exception {
        byte[] keyAsBytes;
        keyAsBytes = "MySixteenCharKey".getBytes(UNICODE_FORMAT);
        Key key = new SecretKeySpec(keyAsBytes, ALGORITHM);
        return key;
    }
}

Upvotes: 3

Views: 15072

Answers (3)

jeet.chanchawat
jeet.chanchawat

Reputation: 2595

Create string extension and use library CryptoSwift

//  String+Addition.swift
import CryptoSwift
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
}

}

and to use

@IBAction func onBtnClicked(_ sender: Any) { 
        let value = "My value to be encrypted"
        let key = "MySixteenCharKey"
        
        print(key!)
        let encryptedValue = try! value.aesEncrypt(key: key!)

        print(encryptedValue)
        
    }

For citation of this particular encryption code:

  1. The 16 char length key implies AES-128
  2. The code is without iVector, This implies ECB mode
  3. Using padding as pkcs5 or pkcs7 did not made any difference in my case

Upvotes: 10

Sanjay Shah
Sanjay Shah

Reputation: 502

Create an extension of String and use this below function for encrypting and decrypting.

extension String {

//MARK: - Encrypt AES Method
/// This method will encrypt and return Cipher string

func aesEncrypt(key: String = "fqJfdzGDvfwbedsKSUGty3VZ9taXxMVw", iv: String = "1234567890123456") -> String {
    if let data = self.data(using: String.Encoding.utf8) {
        do {
            let enc = try AES(key: key, iv: iv, blockMode: .CBC, padding: PKCS7()).encrypt(data.bytes)
            let encData = Data(bytes: enc, count: Int(enc.count))
            let base64String: String = encData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0));
            return base64String
        }
        catch let error {
            print(error.localizedDescription)
            return ""
        }
    }
    return ""
}

//MARK: - Decrypt AES Method
/// This method will decrypt the Cipher string

func aesDecrypt(key: String = "fqJfdzGDvfwbedsKSUGty3VZ9taXxMVw", iv: String = "1234567890123456") -> String {
    if let data = Data(base64Encoded: self, options: Data.Base64DecodingOptions.init(rawValue: 0)) {
        do {
            let dec = try AES(key: key, iv: iv, blockMode: .CBC, padding: PKCS7()).decrypt(data.bytes)
            let decData = Data(bytes: dec, count: Int(dec.count))
            let result = String(data: decData, encoding: .utf8)
            return result ?? ""
        }
        catch let error {
            print(error.localizedDescription)
            return ""
        }
    }

    return ""
    }
}

Upvotes: 0

Shezad
Shezad

Reputation: 756

Try this:

func encryptValue(stringToEncrypt:String) -> String{

    var encryptedString: String = ""

    let value = "MySixteenCharKey"
    let input: Array<UInt8> = Array(stringToEncrypt.utf8)
    let key: Array<UInt8> = Array("MySixteenCharKey".utf8)

    do {
        let encrypted = try AES(key: key, blockMode: .ECB, padding: PKCS7()).encrypt(input)
        let base64 = encrypted.toBase64()
        encryptedString = base64
    } catch {
        print(error)
    }

    return encryptedString
}

Upvotes: 0

Related Questions