0

i am very tensed last 2 days due to encryption / decryption in triple Des in swift i am follow below link but not its show error where i get libraries of CCAlgorithem and CCOptions please check below image and please help me this

Note: I'm New In Swift Xcode

how to add these library in my code i'm new in swift

import UIKit
import CryptoSwift


class CypherSwift: NSObject {


    func tripleDesEncrypt(pass: String) -> String{
        //help from this thread
        //http://stackoverflow.com/questions/25754147/issue-using-cccrypt-commoncrypt-in-swift

        let keyString        = "25d1d4cb0a08403e2acbcbe0"
        let keyData: NSData! = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!

        let message       = pass
        let data: NSData! = (message as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!

        let cryptData    = NSMutableData(length: Int(data.length) + kCCBlockSize3DES)!

        let keyLength              = size_t(kCCKeySize3DES)
        let operation: CCOperation = UInt32(kCCEncrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithm3DES)
        let options:   CCOptions   = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)

        var numBytesEncrypted :size_t = 0

        let cryptStatus = CCCrypt(operation,
                                  algoritm,
                                  options,
                                  keyData.bytes, keyLength,
                                  nil,
                                  data.bytes, data.length,
                                  cryptData.mutableBytes, cryptData.length,
                                  &numBytesEncrypted)

        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)

            // Not all data is a UTF-8 string so Base64 is used
            var base64cryptString = cryptData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)

            print("base64cryptString = \(base64cryptString)")
            base64cryptString = base64cryptString + "\n"
            return encodeString(base64cryptString)

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

    func encodeString(str: String) -> String{
        let customAllowedSet =  NSCharacterSet(charactersInString:"==\n").invertedSet
        let escapedString = str.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
        print("escapedString: \(escapedString)")
        return escapedString!

    }

}

image of error

tiple des link 1

triple des link 2

john
  • 13
  • 4

1 Answers1

1

Unfortunately, there's currently no pre-defined Swift module for CommonCrypto, which means that you'll either have to create one yourself in a module.modulemap file, or import it in your bridging header. If you're making an app and not a framework, the latter is the easiest: just create a bridging header (if you don't have one, just add an Objective-C source file to the project and it'll offer to create one automatically; you can delete the Objective-C source file afterwards). Next, add this to the bridging header:

#import <CommonCrypto/CommonCrypto.h>

Note that if you're making a framework, the bridging header won't work and you'll have to make a modulemap instead (let me know if this is the case, and I'll edit something into the answer).

Anyway, the above will get rid of all the errors about kCC things not being found. Now that that's done, there are still a few things in the code that need fixing.

First of all, get rid of the unnecessary use of NS classes. Change:

let keyData: NSData! = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!

to:

let keyData = keyString.data(using: .utf8)!

The ! is acceptable in this case, since we know what keyString is and we know that it's definitely always convertible to UTF-8.

Now, do the same thing for data. Unfortunately in this case, message depends on user input, so we shouldn't use !—if the message turns out not to be convertible to UTF-8, ! will cause your app to crash, which usually isn't what you want. It's better to use guard let and then bail if the conversion fails, either by making your function's return value optional and returning nil or adding throws to your function's return value and throwing an error:

guard let data = message.data(using: .utf8) else {
    return nil
    OR:
    throw CocoaError(.fileReadInapplicableStringEncoding) // or some custom error
}

The next issue is the use of bytes on your Data object. In Swift, this is not allowed, because it's unsafe; if the Data is deallocated before you're done with bytes, you'll crash or run into other weird behavior. Instead, you should use withUnsafeBytes, and do the work requiring the bytes inside a closure. This is safer, since the Data is guaranteed to be valid at least until the closure returns. Since we have three separate Datas that we need the bytes of, this is kind of unwieldy with a triple-nested closure, but we can do it:

let cryptStatus = keyData.withUnsafeBytes { (keyBytes: UnsafePointer<UInt8>) in
    data.withUnsafeBytes { (dataBytes: UnsafePointer<UInt8>) in
        cryptData.withUnsafeMutableBytes { (cryptBytes: UnsafeMutablePointer<UInt8>) in
            CCCrypt(operation,
                    algoritm,
                    options,
                    keyBytes,
                    keyLength,
                    nil,
                    dataBytes,
                    data.count,
                    cryptBytes,
                    cryptData.count,
                    &numBytesEncrypted)
        }
    }
}

After that, you've just got some more Objective-C-isms to make properly Swifty, and your encrypt function should be done:

cryptData.count = Int(numBytesEncrypted)

// Not all data is a UTF-8 string so Base64 is used
var base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)

The only problem I see in the encode function is a few Objective-C-isms that you should modernize:

let customAllowedSet = CharacterSet(charactersIn: "==\n").inverted
let escapedString = str.addingPercentEncoding(withAllowedCharacters: customAllowedSet)

There's also the calling convention of your encode function; func encodeString(str: String) means you'll have to call it like return encodeString(str: base64cryptString) with the label present. If you want to call it without the label, you can change the signature to func encodeString(_ str: String).

Charles Srstka
  • 16,665
  • 3
  • 34
  • 60
  • how to #import add this file – john Mar 20 '18 at 16:47
  • Thanks for your response . i am working on it can you please answer my above question – john Mar 20 '18 at 16:48
  • @john As I said in the answer, if you add an Objective-C source file to your project, Xcode will offer to automatically create a bridging header for you. You can then delete the Objective-C source file. Add the `#import` line to the bridging header file that Xcode makes. – Charles Srstka Mar 20 '18 at 17:09