【发布时间】:2015-03-09 15:54:57
【问题描述】:
虽然我能够根据 Zaph 和其他人的一些出色示例轻松使用 CCCrypt 进行数据加密和解密 (AES128CBC),但在处理加密/解密文件时,我遇到了两个奇怪的 CCCrypt 问题。
1) 在加密然后解密文件时,我的文件末尾会出现额外的垃圾,并且根据文件的不同而有所不同。一个原始文件的十六进制转储和加密和解密后的结果有一个额外的“0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B”,另一个文件最后有一个额外的“05 05 05 05 05”。两个结果文件的命令行差异报告“文件末尾没有换行符”。除了这些问题(以及处理与这些问题相关的文件的问题,例如 NSJSONSerialization 拒绝解析)之外,一切似乎都在工作。是什么导致了这个令人沮丧的问题?
2) 为了最终容纳非常大的文件,我将文件分成块,然后使用前一个块的最后 16 字节作为下一个块的 IV(因为无论如何这都是 CBC 的工作方式,对吗?) .奇怪的是,在可被密钥大小整除的块上,使用 kCCOption PKCS7Padding 会导致问题。因此,IV 在解密与在这些块之间进行加密时最终会有所不同。当我只是将所有块的选项设置为零时,包括最后一个可能不能被密钥大小整除的块,我得到一个例外。谁能帮我理解这个问题是什么?我只是使用一个条件来避免这个问题,但我不明白这个异常,可能它与问题1有关。
let fileSize = getFileSizeFromPath(filePath)
println("filesize = \(fileSize)")
while file != nil {
if let inputBuffer = file?.readDataOfLength(oneMegaByte) {
if inputBuffer.length == 0 {
file?.closeFile()
break
} else {
println("input buffer length: \(inputBuffer.length)")
if let outputBuffer = inputBuffer.AES128CBC(key: key, iv: iv, encryptionOp: encrypt) {
println("output buffer length: \(outputBuffer.length)")
outFile?.writeData(outputBuffer)
println("input file offset:\(file!.offsetInFile) output file offset:\(outFile!.offsetInFile)")
if encrypt {
let range = NSMakeRange((outputBuffer.length - const.keyLength), const.keyLength)
iv = outputBuffer.subdataWithRange(range)
println("range of iv for next chunk:\(range), iv value: \(iv)")
} else {
let range = NSMakeRange((inputBuffer.length - const.keyLength), const.keyLength)
iv = inputBuffer.subdataWithRange(range)
println("range of iv for next chunk:\(range), iv value: \(iv)")
}
} else {
file?.closeFile()
println("problem encrypting data")
break
}
}
} else {
file?.closeFile()
break
}
以及我添加到 NSData 扩展的方法来加密和解密:
func AES128CBC(#key: NSData, iv: NSData, encryptionOp: Bool) -> NSData? {
if key.length != 16 || iv.length != 16 || key.bytes == iv.bytes {
return nil
}
let data = self
let dataLength = UInt(data.length)
let cPtrToData = UnsafePointer<UInt8>(data.bytes)
let cPtrToIVData = UnsafePointer<UInt8>(iv.bytes)
let cPtrTokeyData = UnsafePointer<UInt8>(key.bytes)
let keySize = size_t(kCCKeySizeAES128)
let buffer: NSMutableData! = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
if buffer == nil { return nil }
var cPtrTobuffer = UnsafeMutablePointer<UInt8>(buffer.mutableBytes)
let bufferSize = size_t(buffer.length)
var operation: CCOperation
if encryptionOp {
operation = UInt32(kCCEncrypt)
} else {
operation = UInt32(kCCDecrypt)
}
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
var options: CCOptions
if dataLength % UInt(const.keyLength) != 0 {
options = UInt32(kCCOptionPKCS7Padding)
} else {
options = 0
}
var encryptedByteCount: UInt = 0
var operationResult = CCCrypt(operation, algoritm, options, cPtrTokeyData, keySize, cPtrToIVData, cPtrToData, dataLength, cPtrTobuffer, bufferSize, &encryptedByteCount)
if UInt32(operationResult) == UInt32(kCCSuccess) {
println("encrypted / decrypted byte count: \(encryptedByteCount)")
buffer.length = Int(encryptedByteCount)
return buffer
}
println("Error: \(operationResult)")
return nil
}
【问题讨论】:
-
以下不正确:“在可被密钥大小整除的块上”,它基于块大小,对于 AES 而言,密钥大小为 16 字节。
-
谢谢.. 我应该设置更改以防我最终移至 256 位。
标签: ios swift aes encryption-symmetric