I was followed this answer to encrypt the data. The encryption is success. But I am stuck with the decrypting the data. I've lot of datas are encrypted. But I used another answers for decryption and decrypted data is not as original. I tried to decrypt the data form the same answer but it is success but the decrypted data is just empty. So, I tried to update the deprication of decryption code but I can't resolve this error when converting clearData
to bytes
in the line let cryptStatus = clearData.withUnsafeBytes { (cryptBytes)
Cannot convert value of type 'UnsafeRawBufferPointer' to expected argument type 'UnsafeMutableRawPointer?'
Can you please help me to resolve the error? Thank you.
import Accelerate
import CommonCrypto
Encryption:
func encrypt() {
let data = "Hello,World".data(using: .utf8)!
let keyData = "SOME_SECRET_CODE".data(using: .utf8)!
if let cryptData = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {
let keyLength = size_t(kCCKeySizeAES128)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
(keyData as NSData).bytes, keyLength,
"",
(data as NSData).bytes, data.count,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
print("Encryption Success...")
cryptData.length = Int(numBytesEncrypted)
self.decrypt(data: cryptData as Data, keyData: keyData)
}else {
print("Encryption isn't success!")
}
}else{
print("Can't encrypt")
}
}
Decryption:
func decrypt(data:Data, keyData:Data){
let keyLength = keyData.count
let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
if (validKeyLengths.contains(keyLength) == false) {
fatalError("Invalid key length")
}
let ivSize = kCCBlockSizeAES128;
let clearLength = size_t(data.count - ivSize)
var clearData = Data(count:clearLength)
var numBytesDecrypted :size_t = 0
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptStatus = clearData.withUnsafeBytes { (cryptBytes) -> CCCryptorStatus in
data.withUnsafeBytes { (dataBytes) -> CCCryptorStatus in
keyData.withUnsafeBytes { (keyBytes) -> CCCryptorStatus in
return CCCrypt(CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES128),
options,
keyBytes, keyLength,
dataBytes,
dataBytes+kCCBlockSizeAES128, clearLength,
cryptBytes, clearLength, // Error here
&numBytesDecrypted)
}
}
}
/*
let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in
data.withUnsafeBytes {dataBytes in
keyData.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES128),
options,
keyBytes, keyLength,
dataBytes,
dataBytes+kCCBlockSizeAES128, clearLength,
cryptBytes, clearLength,
&numBytesDecrypted)
}
}
}
*/
clearData.count = numBytesDecrypted
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
clearData.count = numBytesDecrypted
if let string = String(data: clearData, encoding: .utf8){
print("Decrypted: \(string)")
}else{
print("Decryption failed! \(clearData.count)")
}
}
else {
fatalError("Decryption failed")
}
}
Your code needs a little refactoring and you're good to go.
let cryptStatus: CCCryptorStatus = clearData.withUnsafeBytes {cryptBytes in
data.withUnsafeBytes {dataBytes in
keyData.withUnsafeMutableBytes {keyBytes in
return CCCrypt(CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES128),
options,
cryptBytes, keyLength,
dataBytes,
dataBytes+kCCBlockSizeAES128, clearLength,
keyBytes.baseAddress!, clearLength,
&numBytesDecrypted)
}
}
}
Now there will be a compile time error saying Cannot use mutating member on immutable value: 'keyData' is a 'let' constant
In order to get rid of this error, just modify the keyData parameter of your decrypt func like below.
func decrypt(data:Data, keyData: inout Data)
Function Call
self.decrypt(data: cryptData as Data, keyData: &keyData)
inout Parameters: All parameters passed into a Swift function are constants, so you can’t change them. If you want, you can pass in one or more parameters as inout, which means they can be changed inside your function, and those changes reflect in the original value outside the function.