gpt4 book ai didi

ios - CCCrypt iOS Swift 3 中的奇怪行为

转载 作者:搜寻专家 更新时间:2023-11-01 07:13:37 27 4
gpt4 key购买 nike

我在使用 SWIFT 3 进行加密和解密时遇到了一个奇怪的行为.我正在使用以下方法加密和解密字符串。加密时我生成随机盐并将其附加到加密数据的末尾,解密时我从数据中读取 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
}
}

现在出现了奇怪的行为。我调用此方法两次,第一次用于加密,第二次用于解密从上一次调用返回的加密字符串。

现在,如果我运行此代码,则加密将成功进行,但解密返回无效数据 - 这里的 cryptStatus 是成功的,但 bytesDecrypted 显示为 16 并且转换此 tostring 返回 nil。

现在奇怪的是,如果我在加密的其他部分(即从加密字符串中提取 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)

关于这种奇怪行为的任何想法。我需要做任何重置或给予任何延迟吗??

最佳答案

您的代码中的问题在于 withUnsafeByteswithUnsafeMutableBytes 的所有这些用法:

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

检查withUnsafeBytes的引用:

withUnsafeBytes(_:)

Warning

The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.

(您可以为 withUnsafeMutableBytes 找到相同的警告。)

withUnsafeByteswithUnsafeMutableBytes 的所有用法都将指针参数带到闭包之外,这可能会导致任何类型的意外行为,包括崩溃。

withUnsafeByteswithUnsafeMutableBytes 的正确用法是这样的:

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

关于ios - CCCrypt iOS Swift 3 中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43511108/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com