I want to decrypt a DES encrypted String with CommonCrypto.
I already imported CommonCrypto with a Bridging Header into my Project.
By try and error I managed to call CCCrypt function and it even returns kCCSuccess.
But after that my result is still empty.
Here is my code:
if let key = "12345678".data(using: .utf8), let data = "inMyOriginalCodeYouWouldSeeADESEncryptedStringHere/ahw==".data(using: .utf8) {
var numBytesDecrypted: size_t = 0
var result = Data(capacity: data.count)
let err = result.withUnsafeMutableBytes {resultBytes in
data.withUnsafeBytes {dataBytes in
key.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionPKCS7Padding), keyBytes, kCCKeySizeDES, nil, dataBytes, data.count, resultBytes, data.count, &numBytesDecrypted)
}
}
}
if err != CCCryptorStatus(kCCSuccess) {
NSLog("Decryption failed! Error: \(err.description)")
}
print(numBytesDecrypted)
print(result)
return String(data: result, encoding: .utf8) ?? "???"
}
return "???"
}
The output of the two print lines currently is:
56
0 bytes
UPDATE:
Corrected code according to accepted answer:
let encrypted = "inMyOriginalCodeYouWouldSeeADESEncryptedStringHere/ahw=="
if let key = "12345678".data(using: .utf8), let data = Data(base64Encoded: encrypted) {
var numBytesDecrypted: size_t = 0
var result = Data(count: data.count)
let err = result.withUnsafeMutableBytes {resultBytes in
data.withUnsafeBytes {dataBytes in
key.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionECBMode), keyBytes, kCCKeySizeDES, nil, dataBytes, data.count, resultBytes, data.count, &numBytesDecrypted)
}
}
}
if err != CCCryptorStatus(kCCSuccess) {
NSLog("Decryption failed! Error: \(err.description)")
}
return String(data: result, encoding: .utf8) ?? "???"
}
This code now returns the correct result. There is only one little problem left: the returned result String looks like the following now: "encryptedString\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}"
How can I get rid of these last 8 bytes?
I tried to to initialise my result like this:
var result = Data(count: data.count - kCCBlockSizeDES)
but then i get a kCCBufferTooSmall error.
UPDATE2:
I now use CCOptions(kCCOptionPKCS7Padding|kCCOptionECBMode)
but this only changed the "\u{08}" characters to "\0" characters. So now i simply call .trimmingCharacters(in: CharacterSet.controlCharacters)
on my result String before returning it.
When you encrypt or decrypt from String to String, you need 3 steps, as modern encryption algorithms work on only binary data.
Encoding:
(I guess you have a base64 encoded String as your
==
in the encrypted String is suggesting.)So, when decoding, you need all these steps in reverse.
Decoding:
You are doing the first step of decoding in a wrong way. (See #1 of the code below.)
One more, when you want to receive data into mutable (
var
)Data
, setcount
(not onlycapacity
) of theData
. (#2 and #3)UPDATED And, as told by zaph, you need to specify IV for CBC mode (default) or use ECB mode (#4).
Your code should be something like this: