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