swiftencryptionmd53descommoncrypto

MD5 3DES encryption Swift


I have an app that must send login credentials that have been encrypted first by MD5 and then by 3DES.

I have managed to use CryptoSwift to encrypt the string by MD5. However I cannot find anything to encrypt by 3DES on Swift.

I have tried CommonCrypto. As far as I can tell this is in C but could be imported into Objective C with a bridging header.

I have found a few articles and tutorials that tell me how to import CommonCrypto into Swift, either by a bridging header(with the warning it will not work with frameworks) or by Model.map. However neither are working. Im not sure if this is a limitation in the latest versions of iOS or Xcode.

Could someone please advise an alternative?

Thanks

EDITED

Hi, please see the below steps I have taken

  1. Ok so I created a new project called newEncrypt.
  2. I chose not to use the header option as the instructions say this is limited to non Framework apps/
  3. I created a folder inside newEncrypt called CommonCrypto, with a module.map file inside. the contents of which are: module CommonCrypto [system] { header "/usr/include/CommonCrypto/CommonCrypto.h" export * }
  4. added ${SRCROOT}/CommonCrypto to swift compiler-search paths-import paths. Debug and release.
  5. This is where the instructions sort of stop. I assume I need to import CommonCrypto into my class. This error with “could not build objective C module ‘CommonCrypto’. Im also assuming I should have the CommonCrypto library files (from the CommonCryto ‘include’ folder) in "/usr/include/CommonCrypto/CommonCrypto.h" or “/newEncrypt/CommonCrypto/CommonCrypto.h"? I have tried this, but I just get the same errors.
  6. I have then tried to ad a header file with #import and added -lfoo to other linker flags debug and release (although this may not be the correct one) ust in case this could still be required. But I still get the same could not build objective c error. Im sure I am doing something wrong thats obvious

Solution

  • So it turns out I was completely overcomplicating this.

    There is a really useful article already http://www.stackoverflow.dluat.com/questions/31004609/how-to-convert-common-crypto-code-from-objective-c-to-swift

    I didn't need to import any external libraries or SDKs, all I needed was a bridging header and to #import <CommonCrypto/CommonCrypto.h>

    override func viewDidLoad() {
        super.viewDidLoad()
        myEncrypt("my string to encrypt") 
    }
    
    func myEncrypt(encryptData:String) -> NSData?{
    
            var myKeyData : NSData = ("myEncryptionKey" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
            var myRawData : NSData = encryptData.dataUsingEncoding(NSUTF8StringEncoding)!
            var iv : [UInt8] = [56, 101, 63, 23, 96, 182, 209, 205]  // I didn't use
            var buffer_size : size_t = myRawData.length + kCCBlockSize3DES
            var buffer = UnsafeMutablePointer<NSData>.alloc(buffer_size)
            var num_bytes_encrypted : size_t = 0
    
            let operation: CCOperation = UInt32(kCCEncrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithm3DES)
            let options:   CCOptions   = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
            let keyLength        = size_t(kCCKeySize3DES)
    
            var Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, myKeyData.bytes, keyLength, nil, myRawData.bytes, myRawData.length, buffer, buffer_size, &num_bytes_encrypted)
    
            if UInt32(Crypto_status) == UInt32(kCCSuccess){
    
                var myResult: NSData = NSData(bytes: buffer, length: num_bytes_encrypted)
    
                free(buffer)
                println("my result \(myResult)") //This just prints the data
    
                let keyData: NSData = myResult
                let hexString = keyData.toHexString()
                println("hex result \(hexString)") // I needed a hex string output
    
    
                myDecrypt(myResult) // sent straight to the decryption function to test the data output is the same
                return myResult
            }else{
                free(buffer)
                return nil
            }   
        }
    
    
    func myDecrypt(decryptData : NSData) -> NSData?{
    
        var mydata_len : Int = decryptData.length
        var keyData : NSData = ("myEncryptionKey" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
    
        var buffer_size : size_t = mydata_len+kCCBlockSizeAES128
        var buffer = UnsafeMutablePointer<NSData>.alloc(buffer_size)
        var num_bytes_encrypted : size_t = 0
    
        var iv : [UInt8] = [56, 101, 63, 23, 96, 182, 209, 205]  // I didn't use
    
        let operation: CCOperation = UInt32(kCCDecrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithm3DES)
        let options:   CCOptions   = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
        let keyLength        = size_t(kCCKeySize3DES)
    
        var decrypt_status : CCCryptorStatus = CCCrypt(operation, algoritm, options, keyData.bytes, keyLength, nil, decryptData.bytes, mydata_len, buffer, buffer_size, &num_bytes_encrypted)
    
        if UInt32(decrypt_status) == UInt32(kCCSuccess){
    
            var myResult : NSData = NSData(bytes: buffer, length: num_bytes_encrypted)
            free(buffer)
            println("decrypt \(myResult)")
    
            var stringResult = NSString(data: myResult, encoding:NSUTF8StringEncoding)
            println("my decrypt string \(stringResult!)")
            return myResult
        }else{
            free(buffer)
            return nil
    
        }
    }
    

    I hope this helps someone.