Шифрование и дешифрование данных

Шифрование и дешифрование преобразовывают, обеспечивают различные алгоритмы шифрования симметричного блочного шифра, с дополнительным дополнением (PKCS № 1, № 5 и № 7) и поддержка многократных блочных режимов (ECB, CBC, CFB, OFB или единственный блок). Эти преобразования также позволяют Вам указывать вектор инициализации, в подходящих случаях для желаемого блочного режима.

Основной процесс шифрования и дешифрования состоит из двух частей: получение или генерация ключевого объекта в надлежащем формате и выполнении самого преобразования.

Получение объекта SecKeyRef для криптографии с симметричными шифрами

Прежде чем можно будет зашифровать или дешифровать данные, необходимо создать или получить a SecKeyRef объект для ключа шифрования. В дополнение к хранению байтов самого ключа, этой информации об объектно-ориентированных памятях о типе ключа, сохраненного в.

Получение ключа от цепочки для ключей

Во-первых, считайте Сертификат, Ключ и Руководство по программированию Trust Services, чтобы изучить, как получить открытый ключ от цепочки для ключей. Как только Вы получили a SecKeychainItemRef, можно бросить его к a SecKeyRef для использования с этим API.

Генерация случайного симметричного ключа

Если у Вас уже нет ключа шифрования, можно попросить, чтобы OS X генерировал один для Вас путем вызова SecKeyGenerateSymmetric.

bullet
Генерировать случайный симметричный ключ
  1. Создайте словарь параметров, говорящий функции какой ключ генерировать.

    Например, можно создать минимальный словарь параметров для ключа AES как это:

        CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(
        kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
        &kCFTypeDictionaryValueCallBacks);
     
        CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);
  2. Установите размер ключа в 256 битов.

        int32_t rawnum = 256;
        CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,
            kCFNumberSInt32Type, &rawnum);
     
        CFDictionarySetValue(parameters, kSecAttrKeySizeInBits, num);
  3. Генерируйте ключ.

        cryptokey = SecKeyGenerateSymmetric(parameters, &error);

Создание ключевого объекта от существующего ключа

Прежде чем можно будет импортировать или генерировать ключ, необходимо создать словарь параметров для описания ожидаемого содержания того ключа.

Например, можно создать минимальный словарь параметров для ключа AES следующим образом:

    CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(
    kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
    &kCFTypeDictionaryValueCallBacks);
 
    CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);

Если у Вас есть существующий ключ, который Вы хотите использовать для шифрования, необходимо загрузить тот ключ в a CFData объект. Два метода описаны ниже.

  • Если у Вас есть ключ в блоке памяти, можно создать объект из необработанного массива байтов как это:

        CFDataRef cfdatacryptokey = NULL;
     
        /*
           128-bit AES key.  This is for demonstration purposes
           only.  Do NOT hard-code a key into your code.
         */
        const uint8_t rawcryptokeyarr[16] = {
            63, 17, 27, 99, 185, 231, 1, 191,
            217, 74, 141, 16, 12, 99, 253, 41
        };
        void *rawcryptokey = &rawcryptokeyarr;
        size_t keylen = sizeof(rawcryptokey)
     
        cfdatacryptokey = CFDataCreate(
                                       kCFAllocatorDefault,
                                       rawcryptokey,
                                       keylen);
  • Если ключ находится в файле, можно использовать чтение, преобразовывают для получения содержания файла в a CFDataRef объект, как описано в Чтении Файлов.

    Как только у Вас есть ключ a CFData объект, необходимо вызвать SecKeyCreateFromData создать ключевой объект.

        SecKeyRef cryptokey;
     
        cryptokey = SecKeyCreateFromData(parameters,
                                         cfdatacryptokey,
                                         &error);
        if (error) { CFShow(error); exit(-1); }

Выполнение фактического шифрования и дешифрования

Как только у Вас есть объект ключа шифрования, можно создать, преобразовывают объекты и используют их, чтобы зашифровать и дешифровать содержание CFData объекты.

bullet
Выполнять фактическое шифрование и дешифрование
  1. Создайте объекты шифрования.

        SecTransformRef encrypt = NULL, decrypt = NULL;
     
        /* Create the transform objects */
        encrypt = SecEncryptTransformCreate(cryptokey, &error);
        if (error) { CFShow(error); exit(-1); }
        decrypt = SecDecryptTransformCreate(cryptokey, &error);
        if (error) { CFShow(error); exit(-1); }
  2. Набор приписывает на тех объектах указать дополнение, векторы инициализации, и т.д., как желаемый.

    Например, для использования дополнения № 7 PKCS Вы использовали бы следующий код:

        SecTransformSetAttribute(
                                 encrypt,
                                 kSecPaddingKey,
                                 kSecPaddingPKCS7Key,
                                 &error);
        if (error) { CFShow(error); exit(-1); }
     
        SecTransformSetAttribute(
                                 decrypt,
                                 kSecPaddingKey,
                                 kSecPaddingPKCS7Key,
                                 &error);
        if (error) { CFShow(error); exit(-1); }
  3. Установите входные атрибуты и выполните преобразования.

        CFDataRef sourceData = ...
     
        CFDataRef encryptedData = NULL;
        CFDataRef decryptedData = NULL;
        CFErrorRef error = NULL;
     
        /* Use the sourceData object as input to the encryption object. */
        SecTransformSetAttribute(encrypt, kSecTransformInputAttributeName,
                                 sourceData, &error);
        if (error) { CFShow(error); exit(-1); }
     
        /* Encrypt the data. */
        encryptedData = SecTransformExecute(encrypt, &error);
        if (error) { CFShow(error); exit(-1); }
     
        /* Use the encrypted data as input to the decryption object. */
        SecTransformSetAttribute(decrypt, kSecTransformInputAttributeName,
                                 encryptedData, &error);
        if (error) { CFShow(error); exit(-1); }
     
        /* Decrypt the data. */
        decryptedData = SecTransformExecute(decrypt, &error);
        if (error) { CFShow(error); exit(-1); }