Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CCCrypt iOS Swift 3中的奇怪行为_Ios_Iphone_Swift - Fatal编程技术网

CCCrypt iOS Swift 3中的奇怪行为

CCCrypt iOS Swift 3中的奇怪行为,ios,iphone,swift,Ios,Iphone,Swift,我在使用SWIFT 3进行加密和解密时遇到了一个奇怪的行为 。我使用以下方法对字符串进行加密和解密。加密时,我生成一个随机salt并将其发送到加密数据的末尾;解密时,我从数据中读取IV数据以进行解密并执行解密操作 internal func cryptography(_ inputData: Data, key: String, operation: CCOperation) -> Data? { //prepare the Key let keyData: Data!

我在使用SWIFT 3进行加密和解密时遇到了一个奇怪的行为 。我使用以下方法对字符串进行加密和解密。加密时,我生成一个随机salt并将其发送到加密数据的末尾;解密时,我从数据中读取IV数据以进行解密并执行解密操作

internal func cryptography(_ inputData: Data, key: String, operation: CCOperation) -> Data? {

    //prepare the Key
    let keyData: Data!    = key.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    let keyBytes          = keyData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
        return bytes
    }
    let keyLength        = size_t(kCCKeySizeAES128)

    //Prepare the input data

    //Check whether this is encryption , if so generate a random  IV and append this to the encrypted data
    let ivBuffer:UnsafePointer<UInt8>?
    let dataBytes: UnsafePointer<UInt8>?
    var dataLength :Int? = 0
    var ivData :Data? = nil
    if (operation == CCOperation(kCCEncrypt)){

        ivData = self.generateIV()
        ivBuffer = (ivData == nil) ? nil : ivData!.withUnsafeBytes({ (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        })
        dataBytes        = inputData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        }
        dataLength = Int(inputData.count)
    }
    else{

        //for decryption the last 16 bytes will be the IV so extract it
        var dataToProcess  = inputData
        let rangStart = inputData.count - kCCBlockSizeAES128
        let rangeEnd = rangStart + kCCBlockSizeAES128
        var range = Range(rangStart..<rangeEnd)
        ivData = inputData.subdata(in:range)
        ivBuffer = ivData?.withUnsafeBytes({ (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        })

        range = Range(0..<rangStart)
        dataToProcess = inputData.subdata(in: range)
        dataBytes        = dataToProcess.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        }
        dataLength = Int(dataToProcess.count)
    }


    //Calculate buffer details
    var bufferData       = Data(count: Int(dataLength!) + kCCBlockSizeAES128)
    let bufferPointer    = bufferData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
        return bytes
    }
    let bufferLength     = size_t(bufferData.count)


    var bytesDecrypted   = Int(0)
    let tst = CCCryptorStatus()
    let cryptStatus = CCCrypt(
        operation,                      // Operation
        CCAlgorithm(kCCAlgorithmAES128),   // Algorithm is AES
        CCOptions(kCCOptionPKCS7Padding), //options
        keyBytes,                       // key data
        keyLength,                      // key length
        ivBuffer,                            // IV buffer
        dataBytes,                      // input data
        dataLength!,                     // input length
        bufferPointer,                  // output buffer
        bufferLength,                   // output buffer length
        &bytesDecrypted)                // output bytes decrypted real length
    if Int32(cryptStatus) == Int32(kCCSuccess) {
        bufferData.count = bytesDecrypted // Adjust buffer size to real bytes




        if (operation == CCOperation(kCCEncrypt)){

            bufferData.append(ivData!)
        }
        return bufferData as Data
    } else {
        print("Error in crypto operation: \(cryptStatus)")
        return nil
    }
}
内部func加密(\inputData:Data,key:String,operation:CCOperation)->Data?{
//准备钥匙
let keyData:Data!=key.Data(使用:String.Encoding.utf8,allowLossyConversion:false)!
让keyBytes=keyData.withUnsafeBytes{(字节:UnsafePointer)->中的UnsafePointer
返回字节
}
let keyLength=大小(kCCKeySizeAES128)
//准备输入数据
//检查这是否是加密,如果是,则生成随机IV并将其附加到加密数据
让ivBuffer:未安全指针?
让数据字节:未安全指针?
变量数据长度:Int?=0
var ivData:数据?=nil
if(operation==coperation(kCCEncrypt)){
ivData=self.generateIV()
ivBuffer=(ivData==nil)?nil:ivData!。在中包含unsafebytes({(bytes:UnsafePointer)->UnsafePointer
返回字节
})
dataBytes=inputData.withUnsafeBytes{(字节:UnsafePointer)->中的UnsafePointer
返回字节
}
dataLength=Int(inputData.count)
}
否则{
//对于解密,最后16个字节将是IV,因此提取它
var dataToProcess=inputData
让rangStart=inputData.count-kccblocksizeaaes128
让rangeEnd=rangStart+KCCBlocksizeeAes128
变量范围=范围(rangStart..UnsafePointer in
返回字节
})
范围=范围(0..UnsafePointer in)
返回字节
}
dataLength=Int(dataToProcess.count)
}
//计算缓冲区详细信息
var bufferData=Data(计数:Int(数据长度!)+KCCBLOCKSIZEAAES128)
让bufferPointer=bufferData.withUnsafeMutableBytes{(字节:UnsafeMutablePointer)->中的UnsafeMutablePointer
返回字节
}
让bufferLength=size\u t(bufferData.count)
var bytesDecrypted=Int(0)
设tst=CCCryptorStatus()
let cryptStatus=CCCrypt(
操作,//操作
CCAlgorithm(kCCAlgorithmAES128),//算法为AES
cOptions(kCCOptionPKCS7Padding),//选项
keyBytes,//密钥数据
keyLength,//键长度
ivBuffer,//IV buffer
数据字节,//输入数据
dataLength!,//输入长度
bufferPointer,//输出缓冲区
bufferLength,//输出缓冲区长度
&bytesDecrypted)//输出字节解密的实际长度
如果Int32(cryptStatus)==Int32(kCCSuccess){
bufferData.count=bytesDecrypted//将缓冲区大小调整为实字节
if(operation==coperation(kCCEncrypt)){
bufferData.append(ivData!)
}
将缓冲区数据作为数据返回
}否则{
打印(“加密操作出错:\(cryptStatus)”)
归零
}
}
现在出现了奇怪的行为。 我调用这个方法两次,第一次用于加密,第二次用于解密从上一次调用返回的加密字符串

现在,如果我运行这段代码,那么加密将成功进行,但解密返回无效数据-cryptStatus在此为success,但bytesDecrypted显示为16,而将此转换为字符串将返回nil

现在奇怪的是,如果我在加密的else部分(即从加密字符串中提取IV的方法)放置一个断点,即在下面的最后一行,那么如果使用po将dataToProcess和ivData打印到控制台,则解密正确进行

//for decryption the last 16 bytes will be the IV so extract it
    var dataToProcess  = inputData
    let rangStart = inputData.count - kCCBlockSizeAES128
    let rangeEnd = rangStart + kCCBlockSizeAES128
    var range = Range(rangStart..<rangeEnd)
    ivData = inputData.subdata(in:range)
    ivBuffer = ivData?.withUnsafeBytes({ (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
        return bytes
    })

    range = Range(0..<rangStart)
    dataToProcess = inputData.subdata(in: range)
    dataBytes        = dataToProcess.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
        return bytes
    }
    dataLength = Int(dataToProcess.count)
//对于解密,最后16个字节将是IV,因此提取它
var dataToProcess=inputData
让rangStart=inputData.count-kccblocksizeaaes128
让rangeEnd=rangStart+KCCBlocksizeeAes128
变量范围=范围(rangStart..UnsafePointer in
返回字节
})
范围=范围(0..UnsafePointer in)
返回字节
}
dataLength=Int(dataToProcess.count)

你知道这种奇怪的行为吗?我需要重置或延迟吗?

你的代码中有什么不好的地方是使用
不安全字节
不安全字节

    let keyBytes          = keyData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
        return bytes
    }

更新..如果我只打印(po)了“dataToProcess”变量,文本解密正确,仍然很困惑???非常好,非常感谢:)
func cryptography(_ inputData: Data, key: String, operation: CCOperation) -> Data? {
    
    //prepare the Key
    let keyData = key.data(using: .utf8, allowLossyConversion: false)!
    let keyLength = kCCKeySizeAES128
    
    //Prepare the input data
    
    //Check whether this is encryption , if so generate a random  IV and append this to the encrypted data
    let ivData :Data
    let data: Data
    if operation == CCOperation(kCCEncrypt) {
        ivData = self.generateIV()
        data = inputData
    } else {
        //for decryption the last 16 bytes will be the IV so extract it
        let rangStart = inputData.count - kCCBlockSizeAES128
        let rangeEnd = inputData.count
        ivData = inputData.subdata(in: rangStart..<rangeEnd)
        data = inputData.subdata(in: 0..<rangStart)
    }
    let dataLength = data.count
    
    //Calculate buffer details
    var bufferData       = Data(count: dataLength + kCCBlockSizeAES128)
    let bufferLength     = bufferData.count
    
    var bytesDecrypted   = 0
    let cryptStatus = keyData.withUnsafeBytes {keyBytes in
        ivData.withUnsafeBytes {ivBuffer in
            data.withUnsafeBytes {dataBytes in
                bufferData.withUnsafeMutableBytes {bufferPointer in
                    CCCrypt(
                        operation,                      // Operation
                        CCAlgorithm(kCCAlgorithmAES128),   // Algorithm is AES
                        CCOptions(kCCOptionPKCS7Padding), //options
                        keyBytes,                       // key data
                        keyLength,                      // key length
                        ivBuffer,                            // IV buffer
                        dataBytes,                      // input data
                        dataLength,                     // input length
                        bufferPointer,                  // output buffer
                        bufferLength,                   // output buffer length
                        &bytesDecrypted)                // output bytes decrypted real length
                }
            }
        }
    }
    
    if cryptStatus == Int32(kCCSuccess) {
        bufferData.count = bytesDecrypted // Adjust buffer size to real bytes
        if operation == CCOperation(kCCEncrypt) {
            bufferData.append(ivData)
        }
        return bufferData
    } else {
        print("Error in crypto operation: \(cryptStatus)")
        return nil
    }
}