【问题标题】:DES Encryption and decryption algorithm in swiftswift中的DES加密解密算法
【发布时间】:2019-02-25 09:13:02
【问题描述】:

我正在尝试使用 DES 算法在 swift 中进行加密和解密

但是对于我编写的代码,加密消息在每次构建时都会发生变化

这是我的代码:

import UIKit
import CommonCrypto

public class IAppEncryptionUtitlity: NSObject {
    private override init(){}
    public static let sharedNetworkVar: IAppEncryptionUtitlity = IAppEncryptionUtitlity()
    let key = IAppConfig.key
     func myEncrypt(encryptData:String) -> NSData?{

        var myKeyData : NSData = ("DyfmgL9p" as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData
        var myRawData : NSData = encryptData.data(using: String.Encoding.utf8)! as NSData
        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>.allocate(capacity: 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)
            print("my result \(myResult)") //This just prints the data

            let keyData: NSData = myResult

            let hexString = keyData.hexEncodedString()
            print("hex result \(keyData)") // I needed a hex string output


            //myDecrypt(decryptData: 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).data(using: String.Encoding.utf8.rawValue)! as NSData

        var buffer_size : size_t = mydata_len+kCCBlockSizeAES128
        var buffer = UnsafeMutablePointer<NSData>.allocate(capacity: 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(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)
            print("decrypt \(myResult)")

            var stringResult = NSString(data: myResult as Data, encoding:String.Encoding.utf8.rawValue)
            print("my decrypt string \(stringResult!)")
            return myResult
        }else{
            free(buffer)
            return nil

        }
    }
}
extension NSData {
    struct HexEncodingOptions: OptionSet {
        let rawValue: Int
        static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
    }

    func hexEncodedString(options: HexEncodingOptions = []) -> String {
        let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
        //var map = { String(format: format, $0) }.joined()

        return ""
    }
}

每次构建的输出都在变化。代码有什么问题或

而且kCCOptionPKCS7Padding和kCCOptionPKCS5Padding是一样的吗?

提前致谢

【问题讨论】:

  • 不幸的是,作为只尝试过一次 Swift 的人(尽管我猜这更像是 ObjectiveC 而不是 Swift),我没有立即看到错误。但是,关于您关于填充的最后一个问题,that I can answer
  • 你应该给出一些输入和输出,以便一些可以测试。
  • 您还应该证明您在 2019 年使用 DES 的原因...
  • @LukeJoshuaPark 因为它早已在 .net 和 android 中实现,现在在 iOS 中实现了相同的功能,所以除了 DES 没有其他选择
  • 嗯,您确实有许多其他选择 - 例如将 .NET 和 Android 更改为使用 AES。您是否知道 DES 密钥可以在标准笔记本电脑上在几个小时内被破解?

标签: ios swift encryption des


【解决方案1】:

通过更改代码得到解决方案

import UIKit
import CommonCrypto
var message: String?

public class IAppEncryptionUtitlity: NSObject {

   //Calling method to encrypt using extensions
    public func methodToCallEncryption( stringToEncrypt : String ) ->String {
        let iVValue:String = "nzug8FrX"
        let keyValue = IAppConfig.key //DyfmgL9p
        let encoded = stringToEncrypt.desEncrypt( key : keyValue , iv : iVValue )
        return encoded!
    }

    public func methodToCallDecryption( stringToDecrypt : String ) -> String{
        let iVValue:String = "nzug8FrX"
        let keyValue = IAppConfig.key //DyfmgL9p
        let decoded = stringToDecrypt.desEncrypt( key : keyValue , iv : iVValue )
        return decoded!
    }
}
extension String {

    func desEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = self.data(using: String.Encoding.utf8),
            let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeDES) {


            let keyLength              = size_t(kCCKeySizeDES)
            let operation: CCOperation = UInt32(kCCEncrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmDES)
            let options:   CCOptions   = UInt32(options)



            var numBytesEncrypted :size_t = 0

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

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
                return base64cryptString

            }
            else {
                return nil
            }
        }
        return nil
    }

    func desDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
            let cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeDES) {

            let keyLength              = size_t(kCCKeySizeDES)
            let operation: CCOperation = UInt32(kCCDecrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmDES)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

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

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
                return unencryptedMessage
            }
            else {
                return nil
            }
        }
        return nil
    }
}

感谢大家的帮助

【讨论】:

    【解决方案2】:

    我们可以使用如下所示的字符串类别来进行所有对称加密和解密,包括 DES、3DES 和 AES。

    /// Extension for Symmetric Encryption and Decryption with DES, 3DES, AES algorithms
    extension String {
        
        /// Encrypts message with DES algorithm
        func desEncrypt(key:String) -> String? {
            
            return symetricEncrypt(key: key, blockSize: kCCBlockSizeDES, keyLength: size_t(kCCKeySizeDES), algorithm: UInt32(kCCAlgorithmDES))
        }
        
        /// Encrypts message with 3DES algorithm
        func tripleDesEncrypt(key:String) -> String? {
            
            return symetricEncrypt(key: key, blockSize: kCCBlockSize3DES, keyLength: size_t(kCCKeySize3DES), algorithm: UInt32(kCCAlgorithm3DES))
        }
        
        /// Encrypts message with AES 128 algorithm
        func aes128Encrypt(key:String) -> String? {
            
            return symetricEncrypt(key: key, blockSize: kCCBlockSizeAES128, keyLength: size_t(kCCKeySizeAES128), algorithm: UInt32(kCCAlgorithmAES128))
        }
        
        /// Encrypts message with AES algorithm
        func aesEncrypt(key:String) -> String? {
            
            return symetricEncrypt(key: key, blockSize: kCCBlockSizeAES128, keyLength: size_t(kCCKeySizeAES256), algorithm: UInt32(kCCAlgorithmAES))
        }
        
        /// Encrypts a message with symmetric algorithm
        func symetricEncrypt(key:String, blockSize: Int, keyLength: size_t, algorithm: CCAlgorithm, options: Int = kCCOptionPKCS7Padding) -> String? {
            let keyData = key.data(using: String.Encoding.utf8)! as NSData
            let data = self.data(using: String.Encoding.utf8)! as NSData
            
            let cryptData = NSMutableData(length: Int(data.length) + blockSize)!
    
            let operation: CCOperation = UInt32(kCCEncrypt)
    
            var numBytesEncrypted :size_t = 0
    
            let cryptStatus = CCCrypt(operation,
                                      algorithm,
                                      UInt32(options),
                                      keyData.bytes, keyLength,
                                      nil,
                                      data.bytes, data.length,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)
            
            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
                return base64cryptString
            }
            else {
                return nil
            }
        }
        
        /// Decrypts message with DES algorithm
        func desDecrypt(key:String) -> String? {
            
            return symetricDecrypt(key: key, blockSize: kCCBlockSizeDES, keyLength: size_t(kCCKeySizeDES), algorithm: UInt32(kCCAlgorithmDES))
        }
        
        /// Decrypts message with 3DES algorithm
        func tripleDesDecrypt(key:String) -> String? {
            
            return symetricDecrypt(key: key, blockSize: kCCBlockSize3DES, keyLength: size_t(kCCKeySize3DES), algorithm: UInt32(kCCAlgorithm3DES))
        }
        
        /// Decrypts message with AES 128 algorithm
        func aes128Decrypt(key:String) -> String? {
            
            return symetricDecrypt(key: key, blockSize: kCCBlockSizeAES128, keyLength: size_t(kCCKeySizeAES128), algorithm: UInt32(kCCAlgorithmAES128))
        }
        
        /// Decrypts message with AES algorithm
        func aesDecrypt(key:String) -> String? {
            
            return symetricDecrypt(key: key, blockSize: kCCBlockSizeAES128, keyLength: size_t(kCCKeySizeAES256), algorithm: UInt32(kCCAlgorithmAES))
        }
    
        /// Decrypts a message with symmetric algorithm
        func symetricDecrypt(key:String, blockSize: Int, keyLength: size_t, algorithm: CCAlgorithm, options: Int = kCCOptionPKCS7Padding) -> String? {
            if let keyData = key.data(using: String.Encoding.utf8),
                let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
                let cryptData    = NSMutableData(length: Int((data.length)) + blockSize) {
    
                let operation: CCOperation = UInt32(kCCDecrypt)
                var numBytesEncrypted :size_t = 0
    
                let cryptStatus = CCCrypt(operation,
                                          algorithm,
                                          UInt32(options),
                                          (keyData as NSData).bytes, keyLength,
                                          nil,
                                          data.bytes, data.length,
                                          cryptData.mutableBytes, cryptData.length,
                                          &numBytesEncrypted)
    
                if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                    cryptData.length = Int(numBytesEncrypted)
                    let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
                    return unencryptedMessage
                }
                else {
                    return nil
                }
            }
            return nil
        }
    }
    

    完整来源: https://gist.github.com/tharindu/1cf0201492e41f1c287e51abb02902cd

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多