-1

I got this code (and modified it) from Issue using CCCrypt (CommonCrypt) in Swift

I messed around for a while but couldn't get the decrypting function to work.

func AESEncrypt(_ text: String, _ keyString: String) -> String {
    let keyData: NSData! = (keyString as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
    let keyBytes = UnsafeMutableRawPointer(mutating: keyData.bytes)
    let data: NSData! = (text as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
    let dataLength = size_t(data.length)
    let dataBytes = UnsafeMutableRawPointer(mutating: data.bytes)
    let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
    let cryptPointer = UnsafeMutableRawPointer(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 + kCCOptionECBMode)

    var numBytesEncrypted :size_t = 0

    let cryptStatus = CCCrypt(operation,
                              algoritm,
                              options,
                              keyBytes, keyLength,
                              nil,
                              dataBytes, dataLength,
                              cryptPointer, cryptLength,
                              &numBytesEncrypted)

    if UInt32(cryptStatus) == UInt32(kCCSuccess) {
        cryptData!.length = Int(numBytesEncrypted)
        let base64cryptString = cryptData!.base64EncodedString(options: .lineLength64Characters)
        return base64cryptString
    } else {
        return "error"
    }
}

func AESDecrypt(_ text: String, _ keyString: String) -> String {

    let data: NSData! = (text as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
    let keyData: NSData! = (keyString as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
    let keyBytes = UnsafeMutableRawPointer(mutating: keyData.bytes)
    let dataLength = size_t(data.length)
    let dataBytes = UnsafeMutableRawPointer(mutating: data.bytes)
    let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
    let cryptPointer = UnsafeMutableRawPointer(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 + kCCOptionECBMode)

    var numBytesEncrypted :size_t = 0

    let cryptStatus = CCCrypt(operation,
                              algoritm,
                              options,
                              keyBytes, keyLength,
                              nil,
                              dataBytes, dataLength,
                              cryptPointer, cryptLength,
                              &numBytesEncrypted)

    if UInt32(cryptStatus) == UInt32(kCCSuccess) {
        cryptData!.length = Int(numBytesEncrypted)
        let base64cryptString = cryptData!.base64EncodedString(options: .endLineWithLineFeed)
        return base64cryptString
    } else {
        return "error"
    }
}

The AESDecrypt() gives a string that appears to be base64encoded, but I can't get it to return the String value.

Community
  • 1
  • 1
twharmon
  • 4,153
  • 5
  • 22
  • 48
  • Is the question "How do I decode a base64encoded String"? – shallowThought Jan 14 '17 at 09:26
  • Only if the line `let base64cryptString = cryptData!.base64EncodedString(options: .lineLength64Characters)` is actually the original text correctly encoded base64. – twharmon Jan 14 '17 at 09:27
  • From a security standpoint t, and the assumption security is the desired result, it is best to handle an improper key length as an error. Further using a `String` as a key is also a poor idea, if a String is used it should be used to derive a key with PBKFD2. Lastly: Do not use ECB mode, it is insecure, see [ECB mode](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29), scroll down to the Penguin. Instead use CBC mode with a random IV, just prefix the encrypted data with the IV for use in decryption, it does not need to not secret. – zaph Jan 14 '17 at 12:08
  • For an example see [AES encryption in CBC mode with a random IV (Swift 3.0)](http://stackoverflow.com/documentation/swift/7026/aes-encryption/23651/aes-encryption-in-cbc-mode-with-a-random-iv-swift-3-0#t=201701141219379063439) in the SO Documentation area. Probably the best solution is [RNCryptor](https://github.com/RNCryptor/RNCryptor), it puts together all the pieces necessary for a secure solution. – zaph Jan 14 '17 at 12:44
  • You don't get the same results back because the decoding function does not properly reverse the steps done in the encoding function, i.e. it must Base-64 decode the given string, then decode the data, and finally UTF-8 decode the decoded data. – Because of the general issues which @zaph explained, and because there are well-written implementations in the documentation and available as RNCryptor, I have deleted my answer. – Martin R Jan 14 '17 at 12:47
  • @ToWhomItMayConcern: I do not think that the security problems are a reason to downvote the question. It contains code that compiles and demonstrates the problem, which makes it better than many other questions. – Martin R Jan 14 '17 at 12:53

1 Answers1

0

I understand your question as "How do I decode a base64encoded String".

This can be done like this:

let decodedData = Data(base64Encoded: base64Encoded)!
let decodedString = String(data: decodedData, encoding: .utf8)!
shallowThought
  • 19,212
  • 9
  • 65
  • 112