MD5 3DES 加密Swift

MD5 3DES encryption Swift

我有一个应用程序必须发送登录凭据,这些凭据首先由 MD5 加密,然后由 3DES 加密。

我已经设法使用 CryptoSwift 通过 MD5 加密字符串。 但是我在 Swift.

上找不到任何要通过 3DES 加密的内容

我试过 CommonCrypto。据我所知这是在 C 中,但可以通过桥接 header.

导入到 Objective C

我找到了一些文章和教程,它们告诉我如何将 CommonCrypto 导入 Swift,或者通过桥接 header(警告它不适用于框架)或者通过 Model.map。但是两者都不起作用。我不确定这是否是 iOS 或 Xcode.

最新版本的限制

有人可以建议替代方案吗?

谢谢

已编辑

您好,请看下面我采取的步骤

  1. 好的,所以我创建了一个名为 newEncrypt 的新项目。
  2. 我选择不使用 header 选项,因为说明中说这仅限于非框架应用程序/
  3. 我在 newEncrypt 中创建了一个名为 CommonCrypto 的文件夹,里面有一个 module.map 文件。其中的内容是: module CommonCrypto [system] { header "/usr/include/CommonCrypto/CommonCrypto.h" 出口 * }
  4. 将 ${SRCROOT}/CommonCrypto 添加到 swift compiler-search paths-import 路径。调试发布。
  5. 说明到此为止。我假设我需要将 CommonCrypto 导入我的 class。此错误与“无法构建 objective C 模块‘CommonCrypto’。 我还假设我应该在“/usr/include/CommonCrypto/CommonCrypto.h”或“/newEncrypt/CommonCrypto/CommonCrypto.h”中拥有 CommonCrypto 库文件(来自 CommonCryto ‘include’ 文件夹)? 我已经试过了,但我得到了同样的错误。
  6. 然后我尝试使用#import 添加一个 header 文件,并将 -lfoo 添加到其他链接器标志调试和发布(尽管这可能不是正确的),以防万一仍然需要.但我仍然得到同样的 could not build objective c 错误。 我确定我做错了很明显的事情

所以事实证明我完全把它复杂化了。

已经有一篇非常有用的文章了 http://www.Whosebug.dluat.com/questions/31004609/how-to-convert-common-crypto-code-from-objective-c-to-swift

我不需要导入任何外部库或 SDK,我只需要桥接 header 和 #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

    }
}

我希望这对某人有所帮助。

基于@ThundercatChris 和@DarkDust 的解决方案,我在使用十六进制字符串时不得不更改他们的解决方案。需要强制执行三重 DES 密钥长度,因为 encryption/decryption 没有它就无法正常工作。

import Foundation

extension Data {
    private func tripleDesKey() -> Data? {
        if self.count == 24 {
            return self
        }
        
        if self.count == 16 {
            var key = Data(capacity: 24)
            key.append(self.subdata(in: 0..<16))
            key.append(self.subdata(in: 0..<8))
            return key
        }
        
        return nil
    }
    
    private func tripleDesOp(key: Data, operation: CCOperation, options: CCOptions) -> Data? {
        guard let tempKey = key.tripleDesKey() else {
            return nil
        }
        let keyData = NSData(data: tempKey)
        let valueData = NSData(data: self)
        
        let bufferSize = valueData.length +  (UInt32(kCCEncrypt) == operation ? kCCBlockSize3DES : kCCBlockSizeAES128)
        let buffer =  UnsafeMutablePointer<NSData>.allocate(capacity: bufferSize)
        var bytes_encrypted: size_t = 0
        
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithm3DES)
        let keyLength              = size_t(kCCKeySize3DES)

        let ccStatus: CCCryptorStatus = CCCrypt(operation, algoritm, options, keyData.bytes, keyLength, nil, valueData.bytes, valueData.length, buffer, bufferSize, &bytes_encrypted)
        
        guard ccStatus == CCCryptorStatus(kCCSuccess) else {
            free(buffer)
            return nil
        }
        
        let dataOut = Data(bytes: buffer, count: bytes_encrypted)
        free(buffer)
        return dataOut
    }
    
    func tripleDesEncrypt(with key: Data) -> Data? {
        return tripleDesOp(key: key,operation: UInt32(kCCEncrypt), options: UInt32(kCCOptionECBMode))
    }
    
    func tripleDesDecrypt(with key: Data) -> Data?{
        return tripleDesOp(key: key, operation: UInt32(kCCDecrypt), options: UInt32(kCCOptionECBMode))
    }

}