Краткое руководство: шифрование и расшифровка текста с помощью пакета SDK MIP (C++)

В этом кратком руководстве показано, как использовать дополнительные возможности пакетов SDK MIP Protection. Используя один из шаблонов защиты, перечисленных в предыдущем кратком руководстве, вы используете обработчик защиты для шифрования нерегламентированного текста. Класс обработчика защиты предоставляет различные операции для применения и удаления защиты.

Prerequisites

Если вы еще не сделали этого, перед продолжением обязательно выполните следующие предварительные требования:

  • Сначала выполните Краткое руководство. Вывод списка шаблонов защиты (C++), в котором создается начальное решение Visual Studio для перечисления шаблонов защиты, доступных пользователю, прошедшему аутентификацию. Это краткое руководство по шифрованию и расшифровке текста основывается на предыдущем руководстве.
  • При необходимости: просмотрите концепции обработчиков защиты в MIP SDK.

Реализация класса наблюдателя для мониторинга объекта обработчика Защиты

Подобно наблюдателю, который вы реализовали для профиля Protection и ядра в кратком руководстве по инициализации приложения, теперь вы реализуете класс наблюдателя для объектов обработчика Protection.

Создайте базовую реализацию для наблюдателя обработчика защиты, расширив класс пакета SDK mip::ProtectionHandler::Observer . SDK впоследствии создаёт экземпляр наблюдателя и использует его для отслеживания операций обработчика Protection.

  1. Откройте решение в Visual Studio, с которым вы работали в предыдущей статье "Краткое руководство. Вывод списка шаблонов защиты (C++)".

  2. Добавьте в свой проект новый класс, который создаст для вас как файл заголовка (.h), так и файл реализации (.cpp):

    • В Обозреватель решений снова щелкните узел проекта правой кнопкой мыши, выберите "Добавить" и выберите "Класс".
    • В диалоговом окне Добавление класса:
      • В поле "Имя класса" введите handler_observer. Обратите внимание, что Visual Studio автоматически заполняет поля файлов H и .cpp на основе введенного имени.
      • По завершении выберите ОК.
  3. После создания файлов H и .cpp для класса Visual Studio открывает оба файла на вкладках "Группа редакторов". Теперь обновите каждый файл, чтобы реализовать новый класс наблюдателя:

    • Обновите handler_observer.h, выбрав и удалив созданный класс handler_observer. Не удаляйте директивы препроцессора, созданные предыдущим шагом (#pragma, #include). Затем скопируйте и вставьте следующий источник в файл после всех существующих директив препроцессора:

      #include <memory>
      #include "mip/protection/protection_engine.h"
      using std::shared_ptr;
      using std::exception_ptr;
      
      class ProtectionHandlerObserver final : public mip::ProtectionHandler::Observer {
           public:
           ProtectionHandlerObserver() { }
           void OnCreateProtectionHandlerSuccess(const shared_ptr<mip::ProtectionHandler>& protectionHandler, const shared_ptr<void>& context) override;
           void OnCreateProtectionHandlerFailure(const exception_ptr& Failure, const shared_ptr<void>& context) override;
           };
      
      
    • Обновите handler_observer.cpp, выбрав и удалив созданную реализацию класса handler_observer. Не удаляйте директивы препроцессора, созданные предыдущим шагом (#pragma, #include). Затем скопируйте и вставьте следующий источник в файл после всех существующих директив препроцессора:

      #include "handler_observer.h"
      using std::shared_ptr;
      using std::promise;
      using std::exception_ptr;
      
      void ProtectionHandlerObserver::OnCreateProtectionHandlerSuccess(
           const shared_ptr<mip::ProtectionHandler>& protectionHandler,const shared_ptr<void>& context) {
                auto createProtectionHandlerPromise = static_cast<promise<shared_ptr<mip::ProtectionHandler>>*>(context.get());
                createProtectionHandlerPromise->set_value(protectionHandler);
                };
      
      void ProtectionHandlerObserver::OnCreateProtectionHandlerFailure(
           const exception_ptr& Failure, const shared_ptr<void>& context) {
                auto createProtectionHandlerPromise = static_cast<promise<shared_ptr<mip::ProtectionHandler>>*>(context.get());
                createProtectionHandlerPromise->set_exception(Failure);
                };
      
      
  4. При необходимости используйте ctrl+SHIFT+B (сборка решения) для запуска тестовой компиляции и ссылки решения, чтобы убедиться, что она успешно выполняет сборку, прежде чем продолжить.

Добавление логики для шифрования и расшифровки нерегламентированного текста

Добавьте логику для шифрования и расшифровки нерегламентированного текста с помощью объекта подсистемы защиты.

  1. С помощью обозревателя решений откройте файл .cpp в проекте, который содержит реализацию main() метода.

  2. Добавьте следующие директивы #include и using ниже соответствующих существующих директив в начале файла:

      #include "mip/protection_descriptor_builder.h"
      #include "mip/protection_descriptor.h"
      #include "handler_observer.h"
    
      using mip::ProtectionDescriptor;
      using mip::ProtectionDescriptorBuilder;
      using mip::ProtectionHandler;
    
  3. Ближе к концу раздела Main() body, на котором вы остановились в предыдущем кратком руководстве, вставьте следующий код:

    //Encrypt/Decrypt text:
    string templateId = "<Template-ID>";//Template ID from previous QuickStart e.g. "bb7ed207-046a-4caf-9826-647cff56b990"
    string inputText = "<Sample-Text>";//Sample Text
    
    //Refer to ProtectionDescriptor docs for details on creating the descriptor
    auto descriptorBuilder = mip::ProtectionDescriptorBuilder::CreateFromTemplate(templateId);
    const std::shared_ptr<mip::ProtectionDescriptor>& descriptor = descriptorBuilder->Build();
    
    //Create Publishing settings using a descriptor
    mip::ProtectionHandler::PublishingSettings publishingSettings = mip::ProtectionHandler::PublishingSettings(descriptor);
    
    //Create a publishing protection handler using Protection Descriptor
    auto handlerObserver = std::make_shared<ProtectionHandlerObserver>();
    auto pHandlerPromise = std::make_shared<std::promise<std::shared_ptr<ProtectionHandler>>>();
    auto pHandlerFuture = pHandlerPromise->get_future();
    engine->CreateProtectionHandlerForPublishingAsync(publishingSettings, handlerObserver, pHandlerPromise);
    auto publishingHandler = pHandlerFuture.get();
    
    std::vector<uint8_t> inputBuffer(inputText.begin(), inputText.end());
    
    //Show action plan
    cout << "Applying Template ID " + templateId + " to: " << endl << inputText << endl;
    
    //Encrypt buffer using Publishing Handler
    std::vector<uint8_t> encryptedBuffer;
    encryptedBuffer.resize(static_cast<size_t>(publishingHandler->GetProtectedContentLength(inputText.size(), true)));
    
    publishingHandler->EncryptBuffer(0,
                          &inputBuffer[0],
                          static_cast<int64_t>(inputBuffer.size()),
                          &encryptedBuffer[0],
                          static_cast<int64_t>(encryptedBuffer.size()),
                          true);
    
    std::string encryptedText(encryptedBuffer.begin(), encryptedBuffer.end());
    cout << "Encrypted Text :" + encryptedText;
    
    //Show action plan
    cout << endl << "Decrypting string: " << endl << endl;
    
    //Generate publishing license, so it can be used later to decrypt text.
    auto serializedPublishingLicense = publishingHandler->GetSerializedPublishingLicense();
    
    //Use same PL to decrypt the encryptedText.
    auto cHandlerPromise = std::make_shared<std::promise<std::shared_ptr<ProtectionHandler>>>();
    auto cHandlerFuture = cHandlerPromise->get_future();
    shared_ptr<ProtectionHandlerObserver> cHandlerObserver = std::make_shared<ProtectionHandlerObserver>();
    
    //Create consumption settings using serialized publishing license.
    mip::ProtectionHandler::ConsumptionSettings consumptionSettings = mip::ProtectionHandler::ConsumptionSettings(serializedPublishingLicense);
    engine->CreateProtectionHandlerForConsumptionAsync(consumptionSettings, cHandlerObserver, cHandlerPromise);
    
    auto consumptionHandler = cHandlerFuture.get();
    
    //Use consumption handler to decrypt the text.
    std::vector<uint8_t> decryptedBuffer(static_cast<size_t>(encryptedText.size()));
    
    int64_t decryptedSize = consumptionHandler->DecryptBuffer(
         0,
         &encryptedBuffer[0],
         static_cast<int64_t>(encryptedBuffer.size()),
         &decryptedBuffer[0],
         static_cast<int64_t>(decryptedBuffer.size()),
         true);
    
    decryptedBuffer.resize(static_cast<size_t>(decryptedSize));
    
    std::string decryptedText(decryptedBuffer.begin(), decryptedBuffer.end());
    
    // Output decrypted content. Should match original input text.
    cout << "Decrypted Text :" + decryptedText << endl;
    
    
  4. Ближе к концу main() найдите блок завершения работы приложения, созданный в первом кратком руководстве, и добавьте следующие строки, чтобы освободить ресурсы обработчика:

     publishingHandler = nullptr;
     consumptionHandler = nullptr;
    
  5. Замените значения заполнителей в исходном коде следующими строковыми константами:

    Placeholder Ценность
    <пример текста> Пример текста, который вы хотите защитить, например: "cipher text"
    <Идентификатор шаблона> Идентификатор шаблона, который вы хотите использовать для защиты текста. Например: "bb7ed207-046a-4caf-9826-647cff56b990"

Создание и тестирование приложения

Создайте и протестируйте клиентское приложение.

  1. Используйте Ctrl+Shift+B (Собрать решение), чтобы собрать клиентское приложение. Если у вас нет ошибок сборки, используйте F5 (начать отладку) для запуска приложения.

  2. Если ваш проект успешно собирается и запускается, приложение запрашивает токен доступа каждый раз, когда SDK вызывает метод AcquireOAuth2Token(). Как и ранее в кратком руководстве "List protection templates", запустите скрипт PowerShell, чтобы каждый раз получать токен, используя значения, указанные для $authority и $resourceUrl.

    *** Template List:
    Name: Confidential \ All Employees : a74f5027-f3e3-4c55-abcd-74c2ee41b607
    Name: Highly Confidential \ All Employees : bb7ed207-046a-4caf-9826-647cff56b990
    Name: Confidential : 174bc02a-6e22-4cf2-9309-cb3d47142b05
    Name: Contoso Employees Only : 667466bf-a01b-4b0a-8bbf-a79a3d96f720
    Applying Template ID bb7ed207-046a-4caf-9826-647cff56b990 to:
    <Sample-Text>
    Encrypted Text :y¬╩$Ops7Γ╢╖¢t
    Decrypting string:
    
    Run the PowerShell script to generate an access token using the following values, then copy/paste it below:
    Set $authority to: https://login.microsoftonline.com/common/oauth2/authorize
    Set $resourceUrl to: https://aadrm.com
    Sign in with user account: user1@tenant.onmicrosoft.com
    Enter access token: <paste-access-token-here>
    Press any key to continue . . .
    
    Run the PowerShell script to generate an access token using the following values, then copy/paste it below:
    Set $authority to: https://login.microsoftonline.com/94f69844-8d34-4794-bde4-3ac89ad2b664/oauth2/authorize
    Set $resourceUrl to: https://aadrm.com
    Sign in with user account: user1@tenant.onmicrosoft.com
    Enter access token: <paste-access-token-here>
    Press any key to continue . . .
    
    Decrypted Text :<Sample-Text>
    C:\MIP Sample Apps\ProtectionQS\Debug\ProtectionQS.exe (process 8252) exited with code 0.
    To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
    Press any key to close this window . . .
    

Дальнейшие действия