Search code examples
swiftaes

how to use AES with passpharse only


i'm working on app and after the android version done now i have started the ios version using swift 5. i'm using a function in my android version wish is written in java, and using this function i do encrypt/decrypt plain text using aes-256-cbc algorithm.

How can i use this method in CryptoSwift?

    // Java Code

    public class EncryptionDecryption {
    String strResult;

    public  String Encrypt(String text, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] keyBytes = new byte[16];
        byte[] b = key.getBytes("UTF-8");
        int len = b.length;
        if (len > keyBytes.length)
            len = keyBytes.length;
        System.arraycopy(b, 0, keyBytes, 0, len);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

        byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
        Log.v("GET Result from  final:", results.toString());
        strResult = Base64.encodeToString(results, 1);
        return strResult;
    }


    public String Decrypt(String text, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

        byte[] keyBytes = new byte[16];
        byte[] b = key.getBytes("UTF-8");
        int len = b.length;
        if (len > keyBytes.length)
            len = keyBytes.length;
        System.arraycopy(b, 0, keyBytes, 0, len);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] results = new byte[text.length()];
        //BASE64Decoder decoder = new BASE64Decoder();
        try {
            results = cipher.doFinal(Base64.decode(text, Base64.DEFAULT));
        } catch (Exception e) {
            Log.i("Error in Decryption", e.toString());
        }
        return new String(results, "UTF-8");
    }

    }

Solution

  • here is the solution

    import UIKit
    import CryptoSwift
    
    class AES : NSObject {
    
        public static func encrypt(text:String) -> String{
    
            var salted = Data.init(count: 0)
            var dx = Data.init(count: 0)
            let salt = self.randomData(ofLength: 8)
            let passpharse = "passpharse".bytes
            let passAndSalt = passpharse + salt
            while( salted.count < 48){
                dx = MD5(messageData: dx + Data.init(_: passAndSalt))
                salted += dx
            }
    
            let iv = salted.subdata(in: 32..<48)
            let key = salted.subdata(in: 0..<32)
    
            let bytesIV = [UInt8](iv as Data)
            let bytesKey = [UInt8](key as Data)
    
            do {
                let encrypted = try AES(key: bytesKey, blockMode: CBC(iv: bytesIV), padding: .pkcs5)
                let cipherText = try! encrypted.encrypt(text.bytes)
                let saltData = "Salted__".bytes
                let finalData = saltData + salt + cipherText
                return finalData.toBase64()!
            } catch {
                return ""
            }
    
        }
    
        private static func randomData(ofLength length: Int) -> Array<UInt8> {
            var bytes = [UInt8](repeating: 0, count: length)
            let status = SecRandomCopyBytes(kSecRandomDefault, length, &bytes)
            if status == errSecSuccess {
                return bytes
            }
            return Data.init(count: 0).bytes
        }
    
    
        private static func MD5(messageData: Data) -> Data {
            let length = Int(CC_MD5_DIGEST_LENGTH)
            //let messageData = string.data(using:.utf8)!
            var digestData = Data(count: length)
    
            _ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
                messageData.withUnsafeBytes { messageBytes -> UInt8 in
                    if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
                        let messageLength = CC_LONG(messageData.count)
                        CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
                    }
                    return 0
                }
            }
            return digestData
        }
    
    }