问题
I really need some help to convert the objective-c code to swift using CryptoSwift
. I'm not sure how to use functions like: bzero
, getCString
, malloc
in Swift.
+(NSData*)encryptData:(NSData*)data
{
static NSString *key = @"BitCave012345678";
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode,
keyPtr,kCCKeySizeAES128,NULL,[data bytes],dataLength,
buffer, bufferSize, &numBytesEncrypted);
if(cryptStatus == kCCSuccess)
{
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
Does anyone has an idea how to satisfy arguments requiring pointers?
I was trying using UnsafeMutablePointers
and I also tried the code below, but I know it is completely wrong:
var key: NSString = "BitCave012345678"
var keyPtr: Array<Character> = Array<Character>(count: 17, repeatedValue: "0")
bzero(&keyPtr, 17*sizeof(Character))
key.getCString(&keyPtr, maxLength: 17*sizeof(Character), encoding: NSUTF8StringEncoding)
回答1:
Swift 2.0
It is not necessary to use bzero, getCString, malloc, here is an example that does not:
Add Security.framework to the project
Add #import to the bridging header.
// operation is either 'kCCEncrypt' or 'kCCDecrypt'
func testCrypt(data data:NSData, keyData:NSData, operation:Int) -> NSData? {
let keyBytes = UnsafePointer<UInt8>(keyData.bytes)
let dataLength = Int(data.length)
let dataBytes = UnsafePointer<UInt8>(data.bytes)
let cryptData: NSMutableData! = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
let cryptPointer = UnsafeMutablePointer<UInt8>(cryptData.mutableBytes)
let cryptLength = size_t(cryptData.length)
let keyLength = size_t(kCCKeySizeAES128)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(CCOperation(operation),
algoritm,
options,
keyBytes, keyLength,
nil,
dataBytes, dataLength,
cryptPointer, cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
} else {
print("Error: \(cryptStatus)")
}
return cryptData;
}
Example usage:
let keyData = "12345678901234567890123456789012".dataUsingEncoding(NSUTF8StringEncoding)
let messageData = "Don´t try to read this text. Top Secret Stuff".dataUsingEncoding(NSUTF8StringEncoding)
let encrypted = testCrypt(data:messageData!, keyData:keyData!, operation:kCCEncrypt)
Here is version in Swift Arrays
of UInt8 with no NSData
objects:
func testCrypt(data data:[UInt8], keyData:[UInt8], operation:Int) -> [UInt8]? {
let keyBytes = UnsafeMutablePointer<UInt8>(keyData)
let dataLength = data.count
let dataBytes = UnsafeMutablePointer<UInt8>(data)
var cryptData = [UInt8](count:data.count+kCCBlockSizeAES128, repeatedValue:0)
let cryptPointer = UnsafeMutablePointer<UInt8>(cryptData)
let cryptLength = size_t(cryptData.count)
let keyLength = size_t(kCCKeySizeAES128)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(CCOperation(operation),
algoritm,
options,
keyBytes, keyLength,
nil,
dataBytes, dataLength,
cryptPointer, cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeRange(numBytesEncrypted..<cryptData.count)
} else {
print("Error: \(cryptStatus)")
}
return cryptData;
}
Example usage:
let keyData = Array("12345678901234567890123456789012".utf8)
let messageData = Array("Don´t try to read this text. Top Secret Stuff".utf8)
let encrypted = testCrypt(data:messageData, keyData:keyData, operation:kCCEncrypt)
回答2:
I know there are better solutions out there. But I needed legacy support (old DB, already encrypted) so I translated Barts Obj-C code to Swift 5 code. Maybe someone needs it too.
extension Data {
func aesDecrypt() -> Data? {
let myKey:String = "BitCave012345678"
var keyPtr = [Int8](repeating: 0, count: kCCKeySizeAES128+1)
myKey.getCString(&keyPtr, maxLength: keyPtr.count, encoding: String.Encoding.utf8)
var numBytesDecrypted :size_t = 0
let dataLength:Int = self.count
let bufferSize: size_t = dataLength + kCCBlockSizeAES128
let bufferDecrypt = malloc(bufferSize)
let iv = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
let result:CCCryptorStatus = CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmAES128), CCOptions(kCCOptionPKCS7Padding), keyPtr, kCCKeySizeAES128, iv, self.bytes, self.count, bufferDecrypt, bufferSize, &numBytesDecrypted)
if (result == kCCSuccess) {
return Data(bytes: bufferDecrypt!, count: numBytesDecrypted)
}
free(bufferDecrypt)
return nil
}
}
来源:https://stackoverflow.com/questions/32696551/converting-objective-c-code-to-swift