【问题标题】:MD5 3DES encryption SwiftMD5 3DES 加密 Swift
【发布时间】:2015-10-04 15:45:34
【问题描述】:

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

我已经设法使用 CryptoSwift 通过 MD5 加密字符串。 但是我在 Swift 上找不到任何可以通过 3DES 加密的内容。

我已经尝试过 CommonCrypto。据我所知,这是在 C 中,但可以通过桥接头导入到 Objective C 中。

我发现一些文章和教程告诉我如何将 CommonCrypto 导入 Swift,无论是通过桥接头(带有警告它不适用于框架)还是通过 Model.map。但是,两者都不起作用。我不确定这是否是最新版本的 iOS 或 Xcode 的限制。

有人可以提出替代方案吗?

谢谢

已编辑

您好,请查看我已采取的以下步骤

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

【问题讨论】:

  • 当然可以将 CommonCrypto 导入 Swift,尽管它很乏味。正如您所注意到的,您已经找到了几个解释该过程的站点。如果不知道您尝试过什么以及遇到过什么问题,就不可能知道替代方案是什么。 “都不工作”并不能告诉我们您的问题是什么。
  • MD5 是哈希而不是加密,可以使用查找表轻松反转 (md5.gromweb.com)
  • 感谢您这么快回复。我关注了spin.atomicobject.com/2015/02/23/c-libraries-swift 一个。我试图添加一个带有模块 CommonCrypto [system] { header "/usr/include/CommonCrypto/CommonCrypto.h" export * } 的 Model.map 文件作为项目中 CommonCrypto 文件夹中的内容。我已将 CommonCrypto 库添加到同一位置以及我的用户文件夹中的包含文件夹。我还将位置添加到 swift 编译器导入路径
  • @ThundercatChris 您链接的文章看起来不错。是的,这应该有效。您应该更新您的问题,以准确解释您所做的事情以及遇到的问题(什么错误?什么症状?您收到警告吗?您的计算机是否着火了?)您应该从一个空项目开始,然后在实际项目中尝试之前先练习让 CommonCrypto 链接。
  • @RobNapier 我已经编辑了我的原始问题,以包括我在一个新项目中采取的步骤

标签: swift encryption md5 3des commoncrypto


【解决方案1】:

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

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))
    }

}

【讨论】:

    【解决方案2】:

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

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

    我不需要导入任何外部库或 SDK,我只需要一个桥接头和 #import &lt;CommonCrypto/CommonCrypto.h&gt;

    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
    
        }
    }
    

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

    【讨论】:

    • 我做的和上面一样。但我无法从加密数据中解密文本。您可以通过解密文本来更新答案吗?
    • @BalajiRamakrishnan 我得到了 50% 的时间。
    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    相关资源
    最近更新 更多