我想在我的cocoa应用程序中使用AES256加密一些文件。 生成的文件应尽可能小。
这是我的代码:
static func encryptFile(pathToFile:String, destinationPath:String, key:String) -> Bool {
var error: NSError?
let fileContents = NSData(contentsOfFile: pathToFile, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &error)
if let fileContents = fileContents {
println("Trying to encrypt file \(pathToFile)")
let startTime = NSDate().timeIntervalSince1970
let encryptedContents = FileEncryptor.AES256Encryption(fileContents, key: key)
println("ENCRYPTION TIME: \(NSDate().timeIntervalSince1970 - startTime)")
if let encryptedContents = encryptedContents {
var writeError: NSError?
if (encryptedContents.writeToFile(pathToFile, options: NSDataWritingOptions.DataWritingAtomic, error: &writeError)) {
return true
} else {
if (writeError != nil) {
println("Cannot write to file \(pathToFile). Error: \(writeError)")
} else {
println("Cannot write to file \(pathToFile)")
}
return false
}
} else {
return false
}
} else {
println("Unable to read file \(pathToFile). Error: \(error)");
return false
}
}
static func AES256Encryption(dataToEncrypt:NSData, key:String) -> NSData? {
let keyData: NSData! = (key as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let keyBytes = UnsafeMutablePointer<Void>(keyData.bytes)
print("keyLength = \(keyData.length), keyData = \(keyData)")
let dataLength = size_t(dataToEncrypt.length)
let dataBytes = UnsafeMutablePointer<Void>(dataToEncrypt.bytes)
print("dataLength = \(dataLength)")
let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
let cryptPointer = UnsafeMutablePointer<Void>(cryptData!.mutableBytes)
let cryptLength = size_t(cryptData!.length)
let keyLength = size_t(kCCKeySizeAES256)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding + kCCModeCBC)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyBytes, keyLength,
nil,
dataBytes, dataLength,
cryptPointer, cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
// let x: UInt = numBytesEncrypted
cryptData!.length = Int(numBytesEncrypted)
print("cryptLength = \(numBytesEncrypted)")
return cryptData
} else {
print("Error: \(cryptStatus)")
return nil
}
}
我遇到两件事: 1.加密文件内容看起来像[文件的一小部分]:
a56f 707a 24cb e965 08dd be3d 1a0d 9e7b
b73f c982 2014 fdae fa29 c63d 4588 ee29
7b03 5fb2 96a5 00be 2871 e3e8 af23 4eac
我宁愿拥有它:
ã.FrÚQ÷¬_ÄC¯Q%,™˜$žKÝôÙ„gC€È•GBvn&V9&´fÓ
这是我用来解密的功能:
static func decryptFile(pathToFile:String, destinationPath:String, key:String) -> Bool {
var error: NSError?
let fileContents = NSData(contentsOfFile: pathToFile, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &error)
if let fileContents = fileContents {
println("Trying to decrypt file \(pathToFile)")
let startTime = NSDate().timeIntervalSince1970
let decryptedContents = FileEncryptor.AES256Decryption(fileContents, key: key)
println("DECRYPTION TIME: \(NSDate().timeIntervalSince1970 - startTime)")
return NSFileManager.defaultManager().createFileAtPath(destinationPath, contents:decryptedContents, attributes:nil)
} else {
println("Unable to read file \(pathToFile). Error: \(error)");
return false
}
}
static func AES256Decryption(data:NSData, key: String) -> NSData? {
let keyData: NSData! = (key as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let keyBytes = UnsafeMutablePointer<Void>(keyData.bytes)
print("keyLength = \(keyData.length)")
let dataLength = size_t(data.length)
let dataBytes = UnsafeMutablePointer<Void>(data.bytes)
print("dataLength = \(dataLength), ")
let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
let cryptPointer = UnsafeMutablePointer<Void>(cryptData!.mutableBytes)
let cryptLength = size_t(cryptData!.length)
let keyLength = size_t(kCCKeySizeAES256)
let operation: CCOperation = UInt32(kCCDecrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding + kCCModeCBC)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyBytes, keyLength,
nil,
dataBytes, dataLength,
cryptPointer, cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
// let x: UInt = numBytesEncrypted
cryptData!.length = Int(numBytesEncrypted)
return cryptData
} else {
print("Error: \(cryptStatus)")
return nil
}
}
几乎所有代码都是从SO中获取的,除了我遇到的这些问题外,它似乎工作正常。 我使用的密码对于所有文件都是相同的。
任何帮助将不胜感激!
修改 关于问题2.似乎我使用的代码是为ECB模式准备的,我已经改为CBC。这意味着我必须增加加密数据的大小。进行此更改后,几乎所有文件都能正常工作,除了一个......使用较小的值时工作正常。该死。