What is replacement of CommonCryptor in swift?

Hey,


We are trying to use AES 128 encryption for a app but Common Cryptor is not avilable in Swift. Please suggest the replacement.

Accepted Reply

Common Crypto is still the recommended way to do low-level crypto operations, like AES. Alas, as you’ve noted, it’s not easy to access from Swift. IMO the best way to resolve this issue is to write a small C (or Objective-C) wrapper around the Common Crypto operations you need and then have your Swift code call those. For example, here’s the wrapper I use for AES-128 CBC PKCS#7.

extern NSData * SecEncryptAES128CBCPad(NSData * data, NSData * key, NSData * iv) {
    CCCryptorStatus    err;
    NSMutableData *    result;
    size_t              resultLength;

    NSCParameterAssert(key.length == kCCKeySizeAES128);
    NSCParameterAssert(iv.length == kCCBlockSizeAES128);

    // Padding can expand the data, so we have to allocate space for that.  The rule for block
    // cyphers, like AES, is that the padding only adds space on encryption (on decryption it
    // can reduce space, obviously, but we don't need to account for that) and it will only add
    // at most one block size worth of space.

    result = [[NSMutableData alloc] initWithLength:[data length] + kCCBlockSizeAES128];

    err = CCCrypt(
        kCCEncrypt,
        kCCAlgorithmAES128,
        kCCOptionPKCS7Padding,
        key.bytes, key.length,
        iv.bytes,
        data.bytes, data.length,
        result.mutableBytes,  result.length,
        &resultLength
    );
    assert(err == kCCSuccess);

    // Set the output length to the value returned by CCCrypt.  This is necessary because
    // we have padding enabled, meaning that we might have allocated more space than we needed.

    [result setLength:resultLength];

    return result;
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Common Crypto is still the recommended way to do low-level crypto operations, like AES. Alas, as you’ve noted, it’s not easy to access from Swift. IMO the best way to resolve this issue is to write a small C (or Objective-C) wrapper around the Common Crypto operations you need and then have your Swift code call those. For example, here’s the wrapper I use for AES-128 CBC PKCS#7.

extern NSData * SecEncryptAES128CBCPad(NSData * data, NSData * key, NSData * iv) {
    CCCryptorStatus    err;
    NSMutableData *    result;
    size_t              resultLength;

    NSCParameterAssert(key.length == kCCKeySizeAES128);
    NSCParameterAssert(iv.length == kCCBlockSizeAES128);

    // Padding can expand the data, so we have to allocate space for that.  The rule for block
    // cyphers, like AES, is that the padding only adds space on encryption (on decryption it
    // can reduce space, obviously, but we don't need to account for that) and it will only add
    // at most one block size worth of space.

    result = [[NSMutableData alloc] initWithLength:[data length] + kCCBlockSizeAES128];

    err = CCCrypt(
        kCCEncrypt,
        kCCAlgorithmAES128,
        kCCOptionPKCS7Padding,
        key.bytes, key.length,
        iv.bytes,
        data.bytes, data.length,
        result.mutableBytes,  result.length,
        &resultLength
    );
    assert(err == kCCSuccess);

    // Set the output length to the value returned by CCCrypt.  This is necessary because
    // we have padding enabled, meaning that we might have allocated more space than we needed.

    [result setLength:resultLength];

    return result;
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I am still using Common Cryptor, it is working fine. I thought there is some other option in swift.


Thank you for your answer.

Quinn


You always have the best answer!


To start I know almost nothing about crypto. But I need to encrypt some information going to a webservice. It is being decrypted by default SJCL, which I understand to be AES 128 bits in CCM mode. Your code encrypts to AES-128 CBC PKCS#7. Is changing the mode just a case of changing the kCCOption... or is there lots more I need to worry about?


Thanks!


Ken

Unfortunately Common Crypto does not give you access to AES CCM (or AES GCM) via its public API. I believe it’s possible to implement AES CCM is terms of AES ECB, but I’m not the right person to explain how to do that; OTOH, a ’net search for “implementing aes ccm in terms of aes ecb” turned up some interesting results.

Oh, and please do file an enhancement request against Common Crytpo asking for CCM support to be made public. I’d appreciate you posting your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"