Compartilhar via


Guia do desenvolvedor da Proteção de Informações do Windows (WIP)

Um aplicativo habilitado diferencia entre dados corporativos e pessoais e sabe quais proteger com base nas políticas de Proteção de Informações do Windows (WIP) definidas pelo administrador.

Neste guia, mostraremos como criar um. Quando terminar, os administradores de política poderão confiar em seu aplicativo para consumir os dados da organização. E os funcionários vão adorar saber que os dados pessoais deles ficarão intactos no dispositivo mesmo se eles cancelarem a inscrição do gerenciamento de dispositivo móvel (MDM) da organização ou saírem completamente da organização.

Observação Este guia ajuda você a esclarecer um aplicativo UWP. Se você quiser habilitar um aplicativo da área de trabalho do Windows C++, consulte o guia do desenvolvedor da Proteção de Informações do Windows (WIP) (C++).

Você pode ler mais sobre WIP e aplicativos habilitados aqui: Proteção de Informações do Windows (WIP).

Você pode encontrar uma amostra completa aqui.

Se você estiver pronto para passar por cada tarefa, vamos começar.

Primeiro, reúna o que você precisa

Você precisará destes:

  • Uma VM (Máquina Virtual) de teste que executa o Windows 10, versão 1607 ou posterior. Você depurará seu aplicativo nessa VM de teste.

  • Um computador de desenvolvimento que executa o Windows 10, versão 1607 ou posterior. Essa pode ser sua VM de teste se você tiver o Visual Studio instalado nela.

Configurar seu ambiente de desenvolvimento

Você fará o seguinte:

Instale o Assistente do Desenvolvedor de Configuração da WIP em sua VM de teste

Use essa ferramenta para configurar uma política de Proteção de Informações do Windows em sua VM de teste.

Baixe a ferramenta aqui: WIP Setup Developer Assistant.

Crie uma política de proteção

Defina sua política adicionando informações a cada seção no assistente de desenvolvedor de configuração da WIP. Escolha o ícone de ajuda ao lado de qualquer configuração para saber mais sobre como usá-la.

Para obter diretrizes mais gerais sobre como usar essa ferramenta, consulte a seção Notas de versão na página de download do aplicativo.

Configurar um projeto do Visual Studio

  1. No computador de desenvolvimento, abra o projeto.

  2. Adicione uma referência às extensões de desktop e móveis para a Plataforma Universal do Windows (UWP).

    Adicionar extensões UWP

  3. Adicione esse recurso ao arquivo de manifesto do pacote:

       <rescap:Capability Name="enterpriseDataPolicy"/>
    

    Leitura opcional: O prefixo "rescap" significa Capacidade Restrita. Consulte Recursos especiais e restritos.

  4. Adicione este namespace ao arquivo de manifesto do pacote:

      xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    
  5. Adicione o prefixo de namespace ao elemento do arquivo de manifesto <ignorableNamespaces> do pacote.

        <IgnorableNamespaces="uap mp rescap">
    

    Dessa forma, se o aplicativo for executado em uma versão do sistema operacional Windows que não dá suporte a recursos restritos, o Windows ignorará o enterpriseDataPolicy recurso.

Configurar depuração remota

Instale as Ferramentas Remotas do Visual Studio em sua VM de teste somente se você estiver desenvolvendo seu aplicativo em um computador diferente de sua VM. Em seguida, no computador de desenvolvimento, inicie o depurador remoto e veja se o aplicativo é executado na VM de teste.

Consulte as instruções do PC remoto.

Adicionar esses namespaces aos seus arquivos de código

Adicione-as instruções using à parte superior de seus arquivos de código (os snippets neste guia as usam):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.EnterpriseData;
using Windows.Web.Http;
using Windows.Storage.Streams;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml;
using Windows.ApplicationModel.Activation;
using Windows.Web.Http.Filters;
using Windows.Storage;
using Windows.Data.Xml.Dom;
using Windows.Foundation.Metadata;
using Windows.Web.Http.Headers;

Determinar se as APIs de WIP devem ser usadas em seu aplicativo

Verifique se o sistema operacional que executa seu aplicativo dá suporte à WIP e se a WIP está habilitada no dispositivo.

bool use_WIP_APIs = false;

if ((ApiInformation.IsApiContractPresent
    ("Windows.Security.EnterpriseData.EnterpriseDataContract", 3)
    && ProtectionPolicyManager.IsProtectionEnabled))
{
    use_WIP_APIs = true;
}
else
{
    use_WIP_APIs = false;
}

Não chame APIs WIP se o sistema operacional não der suporte a WIP ou se o WIP não estiver habilitado no dispositivo.

Leia dados corporativos

Para ler arquivos protegidos, pontos de extremidade de rede, dados da área de transferência e dados que você aceita de um contrato de compartilhamento, seu aplicativo precisará solicitar acesso.

A Proteção de Informações do Windows concederá permissão ao seu aplicativo se ele estiver na lista de permissões da política de proteção.

Nesta seção:

Ler dados de um arquivo

Etapa 1: obter o identificador de arquivo

    Windows.Storage.StorageFolder storageFolder =
        Windows.Storage.ApplicationData.Current.LocalFolder;

    Windows.Storage.StorageFile file =
        await storageFolder.GetFileAsync(fileName);

Etapa 2: determinar se seu aplicativo pode abrir o arquivo

Chame FileProtectionManager.GetProtectionInfoAsync para determinar se seu aplicativo pode abrir o arquivo.

FileProtectionInfo protectionInfo = await FileProtectionManager.GetProtectionInfoAsync(file);

if ((protectionInfo.Status != FileProtectionStatus.Protected &&
    protectionInfo.Status != FileProtectionStatus.Unprotected))
{
    return false;
}
else if (protectionInfo.Status == FileProtectionStatus.Revoked)
{
    // Code goes here to handle this situation. Perhaps, show UI
    // saying that the user's data has been revoked.
}

Um valor FileProtectionStatus de Protected significa que o arquivo está protegido e seu aplicativo pode abri-lo porque seu aplicativo está na lista de permissões da política.

Um valor FileProtectionStatus de UnProtected significa que o arquivo não está protegido e seu aplicativo pode abrir o arquivo mesmo que seu aplicativo não esteja na lista de permissões da política.

APIs
FileProtectionManager.GetProtectionInfoAsync
FileProtectionInfo
FileProtectionStatus
ProtectionPolicyManager.IsIdentityManaged

Etapa 3: ler o arquivo em um fluxo ou buffer

Ler o arquivo em um fluxo

var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);

Ler o arquivo em um buffer

var buffer = await Windows.Storage.FileIO.ReadBufferAsync(file);

Ler dados de um endpoint de rede

Crie um contexto de thread protegido para ler de um ponto de extremidade corporativo.

Etapa 1: Obter a identidade do endpoint de rede

Uri resourceURI = new Uri("http://contoso.com/stockData.xml");

Windows.Networking.HostName hostName =
    new Windows.Networking.HostName(resourceURI.Host);

string identity = await ProtectionPolicyManager.
    GetPrimaryManagedIdentityForNetworkEndpointAsync(hostName);

Se o ponto de extremidade não for gerenciado pela política, você receberá uma cadeia de caracteres vazia.

APIs
ProtectionPolicyManager.GetPrimaryManagedIdentityForNetworkEndpointAsync

Etapa 2: Criar um contexto de thread protegido

Se o ponto de extremidade for gerenciado pela política, crie um contexto de thread protegido. Isso marca todas as conexões de rede que você faz no mesmo thread para a identidade.

Ele também fornece acesso a recursos de rede corporativa gerenciados por essa política.

if (!string.IsNullOrEmpty(identity))
{
    using (ThreadNetworkContext threadNetworkContext =
            ProtectionPolicyManager.CreateCurrentThreadNetworkContext(identity))
    {
        return await GetDataFromNetworkRedirectHelperMethod(resourceURI);
    }
}
else
{
    return await GetDataFromNetworkRedirectHelperMethod(resourceURI);
}

Este exemplo inclui chamadas de soquete em um using bloco. Se você não fizer isso, feche o contexto do thread depois de recuperar o recurso. Consulte ThreadNetworkContext.Close.

Não crie nenhum arquivo pessoal nesse thread protegido porque esses arquivos serão criptografados automaticamente.

O método ProtectionPolicyManager.CreateCurrentThreadNetworkContext retorna um objeto ThreadNetworkContext independentemente de o ponto de extremidade estar ou não sendo gerenciado pela política. Se o aplicativo lida com recursos pessoais e corporativos, chame ProtectionPolicyManager.CreateCurrentThreadNetworkContext para todas as identidades. Depois de obter o recurso, descarte o ThreadNetworkContext para limpar qualquer marca de identidade do thread atual.

APIs
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity
ProtectionPolicyManager.CreateCurrentThreadNetworkContext

Etapa 3: Ler o recurso em um buffer

private static async Task<IBuffer> GetDataFromNetworkHelperMethod(Uri resourceURI)
{
    HttpClient client;

    client = new HttpClient();

    try { return await client.GetBufferAsync(resourceURI); }

    catch (Exception) { return null; }
}

(Opcional) Usar um token de cabeçalho em vez de criar um contexto de thread protegido

public static async Task<IBuffer> GetDataFromNetworkbyUsingHeader(Uri resourceURI)
{
    HttpClient client;

    Windows.Networking.HostName hostName =
        new Windows.Networking.HostName(resourceURI.Host);

    string identity = await ProtectionPolicyManager.
        GetPrimaryManagedIdentityForNetworkEndpointAsync(hostName);

    if (!string.IsNullOrEmpty(identity))
    {
        client = new HttpClient();

        HttpRequestHeaderCollection headerCollection = client.DefaultRequestHeaders;

        headerCollection.Add("X-MS-Windows-HttpClient-EnterpriseId", identity);

        return await GetDataFromNetworkbyUsingHeaderHelperMethod(client, resourceURI);
    }
    else
    {
        client = new HttpClient();
        return await GetDataFromNetworkbyUsingHeaderHelperMethod(client, resourceURI);
    }

}

private static async Task<IBuffer> GetDataFromNetworkbyUsingHeaderHelperMethod(HttpClient client, Uri resourceURI)
{

    try { return await client.GetBufferAsync(resourceURI); }

    catch (Exception) { return null; }
}

Lidar com redirecionamentos de página

Às vezes, um servidor web redirecionará o tráfego para uma versão mais atual de um recurso.

Para lidar com isso, faça solicitações até que o status de resposta da solicitação tenha um valor OK.

Em seguida, use o URI dessa resposta para obter a identidade do ponto de extremidade. Aqui está uma maneira de fazer isso:

private static async Task<IBuffer> GetDataFromNetworkRedirectHelperMethod(Uri resourceURI)
{
    HttpClient client = null;

    HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
    filter.AllowAutoRedirect = false;

    client = new HttpClient(filter);

    HttpResponseMessage response = null;

        HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, resourceURI);
        response = await client.SendRequestAsync(message);

    if (response.StatusCode == HttpStatusCode.MultipleChoices ||
        response.StatusCode == HttpStatusCode.MovedPermanently ||
        response.StatusCode == HttpStatusCode.Found ||
        response.StatusCode == HttpStatusCode.SeeOther ||
        response.StatusCode == HttpStatusCode.NotModified ||
        response.StatusCode == HttpStatusCode.UseProxy ||
        response.StatusCode == HttpStatusCode.TemporaryRedirect ||
        response.StatusCode == HttpStatusCode.PermanentRedirect)
    {
        message = new HttpRequestMessage(HttpMethod.Get, message.RequestUri);
        response = await client.SendRequestAsync(message);

        try { return await response.Content.ReadAsBufferAsync(); }

        catch (Exception) { return null; }
    }
    else
    {
        try { return await response.Content.ReadAsBufferAsync(); }

        catch (Exception) { return null; }
    }
}

APIs
ProtectionPolicyManager.GetPrimaryManagedIdentityForNetworkEndpointAsync
ProtectionPolicyManager.CreateCurrentThreadNetworkContext
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity

Ler dados da área de transferência

Obter permissão para usar dados da área de transferência

Para obter dados da área de transferência, peça permissão ao Windows. Use DataPackageView.RequestAccessAsync para fazer isso.

public static async Task PasteText(TextBox textBox)
{
    DataPackageView dataPackageView = Clipboard.GetContent();

    if (dataPackageView.Contains(StandardDataFormats.Text))
    {
        ProtectionPolicyEvaluationResult result = await dataPackageView.RequestAccessAsync();

        if (result == ProtectionPolicyEvaluationResult..Allowed)
        {
            string contentsOfClipboard = await dataPackageView.GetTextAsync();
            textBox.Text = contentsOfClipboard;
        }
    }
}

APIs
DataPackageView.RequestAccessAsync

Ocultar ou desabilitar recursos que usam dados da área de transferência

Determine se o modo de exibição atual tem permissão para obter dados que estão na área de transferência.

Caso contrário, você pode desabilitar ou ocultar controles que permitem que os usuários colem informações da área de transferência ou visualizem seu conteúdo.

private bool IsClipboardAllowedAsync()
{
    ProtectionPolicyEvaluationResult protectionPolicyEvaluationResult = ProtectionPolicyEvaluationResult.Blocked;

    DataPackageView dataPackageView = Clipboard.GetContent();

    if (dataPackageView.Contains(StandardDataFormats.Text))

        protectionPolicyEvaluationResult =
            ProtectionPolicyManager.CheckAccess(dataPackageView.Properties.EnterpriseId,
                ProtectionPolicyManager.GetForCurrentView().Identity);

    return (protectionPolicyEvaluationResult == ProtectionPolicyEvaluationResult.Allowed |
        protectionPolicyEvaluationResult == ProtectionPolicyEvaluationResult.ConsentRequired);
}

APIs
ProtectionPolicyEvaluationResult
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity

Impedir que os usuários sejam solicitados com uma caixa de diálogo de consentimento

Um novo documento não é pessoal ou empresarial. É apenas novo. Se um usuário colar dados corporativos nele, o Windows imporá a política e o usuário será solicitado com uma caixa de diálogo de consentimento. Este código impede que isso aconteça. Esta tarefa não é sobre ajudar a proteger os dados. Trata-se mais de impedir que os usuários recebam a caixa de diálogo de consentimento nos casos em que seu aplicativo cria um novo item.

private async void PasteText(bool isNewEmptyDocument)
{
    DataPackageView dataPackageView = Clipboard.GetContent();

    if (dataPackageView.Contains(StandardDataFormats.Text))
    {
        if (!string.IsNullOrEmpty(dataPackageView.Properties.EnterpriseId))
        {
            if (isNewEmptyDocument)
            {
                ProtectionPolicyManager.TryApplyProcessUIPolicy(dataPackageView.Properties.EnterpriseId);
                string contentsOfClipboard = contentsOfClipboard = await dataPackageView.GetTextAsync();
                // add this string to the new item or document here.          

            }
            else
            {
                ProtectionPolicyEvaluationResult result = await dataPackageView.RequestAccessAsync();

                if (result == ProtectionPolicyEvaluationResult.Allowed)
                {
                    string contentsOfClipboard = contentsOfClipboard = await dataPackageView.GetTextAsync();
                    // add this string to the new item or document here.
                }
            }
        }
    }
}

APIs
DataPackageView.RequestAccessAsync
ProtectionPolicyEvaluationResult
ProtectionPolicyManager.TryApplyProcessUIPolicy

Ler dados de um contrato de compartilhamento

Quando os funcionários escolherem seu aplicativo para compartilhar suas informações, seu aplicativo abrirá um novo item que contém esse conteúdo.

Como mencionamos anteriormente, um novo item não é pessoal ou empresarial. É apenas novo. Se o código adicionar conteúdo corporativo ao item, o Windows aplicará a política e o usuário será solicitado com uma caixa de diálogo de consentimento. Este código impede que isso aconteça.

protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
    bool isNewEmptyDocument = true;
    string identity = "corp.microsoft.com";

    ShareOperation shareOperation = args.ShareOperation;
    if (shareOperation.Data.Contains(StandardDataFormats.Text))
    {
        if (!string.IsNullOrEmpty(shareOperation.Data.Properties.EnterpriseId))
        {
            if (isNewEmptyDocument)
                // If this is a new and empty document, and we're allowed to access
                // the data, then we can avoid popping the consent dialog
                ProtectionPolicyManager.TryApplyProcessUIPolicy(shareOperation.Data.Properties.EnterpriseId);
            else
            {
                // In this case, we can't optimize the workflow, so we just
                // request consent from the user in this case.

                ProtectionPolicyEvaluationResult protectionPolicyEvaluationResult = await shareOperation.Data.RequestAccessAsync();

                if (protectionPolicyEvaluationResult == ProtectionPolicyEvaluationResult.Allowed)
                {
                    string text = await shareOperation.Data.GetTextAsync();

                    // Do something with that text.
                }
            }
        }
        else
        {
            // If the data has no enterprise identity, then we already have access.
            string text = await shareOperation.Data.GetTextAsync();

            // Do something with that text.
        }

    }

}

APIs
ProtectionPolicyManager.RequestAccessAsync
ProtectionPolicyEvaluationResult
ProtectionPolicyManager.TryApplyProcessUIPolicy

Proteja os dados corporativos

Proteja os dados corporativos que saem do seu aplicativo. Os dados saem do aplicativo quando você os mostra em uma página, salva em um arquivo ou ponto de extremidade de rede ou por meio de um contrato de compartilhamento.

Nesta seção:

Proteger dados que aparecem em páginas

Quando você mostra dados em uma página, informe ao Windows que tipo de dados são (pessoais ou corporativos). Para fazer isso, marque a visualização do aplicativo atual ou marque todo o processo do aplicativo.

Quando você marca o modo de exibição ou o processo, o Windows impõe a política nele. Isso ajuda a evitar vazamentos de dados resultantes de ações que seu aplicativo não controla. Por exemplo, em um computador, um usuário pode usar CTRL-V para copiar informações corporativas de um modo de exibição e colar essas informações em outro aplicativo. O Windows protege contra isso. O Windows também ajuda a impor contratos de compartilhamento.

Marcar a visualização atual do aplicativo

Faça isso se seu aplicativo tiver várias exibições em que algumas exibições consomem dados corporativos e outras consomem dados pessoais.


// tag as enterprise data. "identity" the string that contains the enterprise ID.
// You'd get that from a file, network endpoint, or clipboard data package.
ProtectionPolicyManager.GetForCurrentView().Identity = identity;

// tag as personal data.
ProtectionPolicyManager.GetForCurrentView().Identity = String.Empty;

APIs
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity

Marque o processo

Faça isso se todas as exibições em seu aplicativo funcionarem com apenas um tipo de dados (pessoal ou corporativo).

Isso evita que você precise gerenciar visualizações marcadas de forma independente.



// tag as enterprise data. "identity" the string that contains the enterprise ID.
// You'd get that from a file, network endpoint, or clipboard data package.
bool result =
            ProtectionPolicyManager.TryApplyProcessUIPolicy(identity);

// tag as personal data.
ProtectionPolicyManager.ClearProcessUIPolicy();

APIs
ProtectionPolicyManager.TryApplyProcessUIPolicy

Proteger dados em um arquivo

Crie um arquivo protegido e grave nele.

Etapa 1: determinar se seu aplicativo pode criar um arquivo corporativo

Seu aplicativo poderá criar um arquivo corporativo se a cadeia de caracteres de identidade for gerenciada pela política e seu aplicativo estiver na lista Permitido dessa política.

  if (!ProtectionPolicyManager.IsIdentityManaged(identity)) return false;

APIs
ProtectionPolicyManager.IsIdentityManaged

Etapa 2: criar o arquivo e protegê-lo para a identidade

StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await storageFolder.CreateFileAsync("sample.txt",
    CreationCollisionOption.ReplaceExisting);

FileProtectionInfo fileProtectionInfo =
    await FileProtectionManager.ProtectAsync(storageFile, identity);

APIs
FileProtectionManager.ProtectAsync

Etapa 3: Gravar esse fluxo ou buffer no arquivo

Escrever um fluxo

    if (fileProtectionInfo.Status == FileProtectionStatus.Protected)
    {
        var stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite);

        using (var outputStream = stream.GetOutputStreamAt(0))
        {
            using (var dataWriter = new DataWriter(outputStream))
            {
                dataWriter.WriteString(enterpriseData);
            }
        }

    }

Escreva um buffer

     if (fileProtectionInfo.Status == FileProtectionStatus.Protected)
     {
         var buffer = Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary(
             enterpriseData, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);

         await FileIO.WriteBufferAsync(storageFile, buffer);

      }

APIs
FileProtectionInfo
FileProtectionStatus

Proteger dados em um arquivo como um processo em segundo plano

Esse código pode ser executado enquanto a tela do dispositivo estiver bloqueada. Se o administrador tiver configurado uma política segura de "Proteção de dados sob bloqueio" (DPL), o Windows removerá as chaves de criptografia necessárias para acessar recursos protegidos da memória do dispositivo. Isso evita vazamentos de dados se o dispositivo for perdido. Esse mesmo recurso também remove chaves associadas a arquivos protegidos quando seus identificadores são fechados.

Você terá que usar uma abordagem que mantenha o identificador de arquivo aberto ao criar um arquivo.

Etapa 1: Determinar se você pode criar um arquivo corporativo

Você poderá criar um arquivo corporativo se a identidade que você está usando for gerenciada pela política e seu aplicativo estiver na lista de permissões dessa política.

if (!ProtectionPolicyManager.IsIdentityManaged(identity)) return false;

APIs
ProtectionPolicyManager.IsIdentityManaged

Etapa 2: criar um arquivo e protegê-lo para a identidade

O FileProtectionManager.CreateProtectedAndOpenAsync cria um arquivo protegido e mantém o identificador de arquivo aberto enquanto você grava nele.

StorageFolder storageFolder = ApplicationData.Current.LocalFolder;

ProtectedFileCreateResult protectedFileCreateResult =
    await FileProtectionManager.CreateProtectedAndOpenAsync(storageFolder,
        "sample.txt", identity, CreationCollisionOption.ReplaceExisting);

APIs
FileProtectionManager.CreateProtectedAndOpenAsync

Etapa 3: Gravar um fluxo ou buffer no arquivo

Este exemplo grava um fluxo em um arquivo.

if (protectedFileCreateResult.ProtectionInfo.Status == FileProtectionStatus.Protected)
{
    IOutputStream outputStream =
        protectedFileCreateResult.Stream.GetOutputStreamAt(0);

    using (DataWriter writer = new DataWriter(outputStream))
    {
        writer.WriteString(enterpriseData);
        await writer.StoreAsync();
        await writer.FlushAsync();
    }

    outputStream.Dispose();
}
else if (protectedFileCreateResult.ProtectionInfo.Status == FileProtectionStatus.AccessSuspended)
{
    // Perform any special processing for the access suspended case.
}

APIs
ProtectedFileCreateResult.ProtectionInfo
FileProtectionStatus
ProtectedFileCreateResult.Stream

Proteger parte de um arquivo

Na maioria dos casos, é mais fácil armazenar dados corporativos e pessoais separadamente, mas você pode armazená-los no mesmo arquivo, se desejar. Por exemplo, o Microsoft Outlook pode armazenar e-mails corporativos junto com e-mails pessoais em um único arquivo morto.

Criptografe os dados corporativos, mas não o arquivo inteiro. Dessa forma, os usuários podem continuar usando esse arquivo mesmo se cancelarem o registro do MDM ou se seus direitos de acesso a dados corporativos forem revogados. Além disso, seu aplicativo deve acompanhar quais dados ele criptografa para saber quais dados proteger ao ler o arquivo de volta na memória.

Etapa 1: Adicionar dados corporativos a um stream ou buffer criptografado

string enterpriseDataString = "<employees><employee><name>Bill</name><social>xxx-xxx-xxxx</social></employee></employees>";

var enterpriseData= Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary(
        enterpriseDataString, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);

BufferProtectUnprotectResult result =
   await DataProtectionManager.ProtectAsync(enterpriseData, identity);

enterpriseData= result.Buffer;

APIs
DataProtectionManager.ProtectAsync
BufferProtectUnprotectResult.buffer

Etapa 2: Adicionar dados pessoais a um fluxo ou buffer não criptografado

string personalDataString = "<recipies><recipe><name>BillsCupCakes</name><cooktime>30</cooktime></recipe></recipies>";

var personalData = Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary(
    personalDataString, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);

Etapa 3: gravar fluxos ou buffers em um arquivo

StorageFolder storageFolder = ApplicationData.Current.LocalFolder;

StorageFile storageFile = await storageFolder.CreateFileAsync("data.xml",
    CreationCollisionOption.ReplaceExisting);

 // Write both buffers to the file and save the file.

var stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite);

using (var outputStream = stream.GetOutputStreamAt(0))
{
    using (var dataWriter = new DataWriter(outputStream))
    {
        dataWriter.WriteBuffer(enterpriseData);
        dataWriter.WriteBuffer(personalData);

        await dataWriter.StoreAsync();
        await outputStream.FlushAsync();
    }
}

Etapa 4: acompanhar a localização dos dados da sua empresa no arquivo

É responsabilidade do seu aplicativo acompanhar os dados nesse arquivo que é de propriedade da empresa.

Você pode armazenar essas informações em uma propriedade associada ao arquivo, em um banco de dados ou em algum texto de cabeçalho no arquivo.

Este exemplo salva essas informações em um arquivo XML separado.

StorageFile metaDataFile = await storageFolder.CreateFileAsync("metadata.xml",
   CreationCollisionOption.ReplaceExisting);

await Windows.Storage.FileIO.WriteTextAsync
    (metaDataFile, "<EnterpriseDataMarker start='0' end='" + enterpriseData.Length.ToString() +
    "'></EnterpriseDataMarker>");

Ler a parte protegida de um arquivo

Veja como você leria os dados corporativos desse arquivo.

Etapa 1: obter a posição dos dados da sua empresa no arquivo

Windows.Storage.StorageFolder storageFolder =
    Windows.Storage.ApplicationData.Current.LocalFolder;

 Windows.Storage.StorageFile metaDataFile =
   await storageFolder.GetFileAsync("metadata.xml");

string metaData = await Windows.Storage.FileIO.ReadTextAsync(metaDataFile);

XmlDocument doc = new XmlDocument();

doc.LoadXml(metaData);

uint startPosition =
    Convert.ToUInt16((doc.FirstChild.Attributes.GetNamedItem("start")).InnerText);

uint endPosition =
    Convert.ToUInt16((doc.FirstChild.Attributes.GetNamedItem("end")).InnerText);

Etapa 2: abra o arquivo de dados e verifique se ele não está protegido

Windows.Storage.StorageFile dataFile =
    await storageFolder.GetFileAsync("data.xml");

FileProtectionInfo protectionInfo =
    await FileProtectionManager.GetProtectionInfoAsync(dataFile);

if (protectionInfo.Status == FileProtectionStatus.Protected)
    return false;

APIs
FileProtectionManager.GetProtectionInfoAsync
FileProtectionInfo
FileProtectionStatus

Etapa 3: ler os dados da empresa do arquivo

var stream = await dataFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);

stream.Seek(startPosition);

Windows.Storage.Streams.Buffer tempBuffer = new Windows.Storage.Streams.Buffer(50000);

IBuffer enterpriseData = await stream.ReadAsync(tempBuffer, endPosition, InputStreamOptions.None);

Etapa 4: Descriptografar o buffer que contém dados corporativos

DataProtectionInfo dataProtectionInfo =
   await DataProtectionManager.GetProtectionInfoAsync(enterpriseData);

if (dataProtectionInfo.Status == DataProtectionStatus.Protected)
{
    BufferProtectUnprotectResult result = await DataProtectionManager.UnprotectAsync(enterpriseData);
    enterpriseData = result.Buffer;
}
else if (dataProtectionInfo.Status == DataProtectionStatus.Revoked)
{
    // Code goes here to handle this situation. Perhaps, show UI
    // saying that the user's data has been revoked.
}

APIs
Informações de proteção de dados
DataProtectionManager.GetProtectionInfoAsync

Proteger dados em uma pasta

Você pode criar uma pasta e protegê-la. Dessa forma, todos os itens adicionados a essa pasta são protegidos automaticamente.

private async Task<bool> CreateANewFolderAndProtectItAsync(string folderName, string identity)
{
    if (!ProtectionPolicyManager.IsIdentityManaged(identity)) return false;

    StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
    StorageFolder newStorageFolder =
        await storageFolder.CreateFolderAsync(folderName);

    FileProtectionInfo fileProtectionInfo =
        await FileProtectionManager.ProtectAsync(newStorageFolder, identity);

    if (fileProtectionInfo.Status != FileProtectionStatus.Protected)
    {
        // Protection failed.
        return false;
    }
    return true;
}

Certifique-se de que a pasta esteja vazia antes de protegê-la. Não é possível proteger uma pasta que já contenha itens.

APIs
ProtectionPolicyManager.IsIdentityManaged
FileProtectionManager.ProtectAsync
FileProtectionInfo.Identity
FileProtectionInfo.Status

Proteger dados em um ponto de extremidade de rede

Crie um contexto de thread protegido para enviar esses dados para um endpoint corporativo.

Etapa 1: Obter a identidade do endpoint de rede

Windows.Networking.HostName hostName =
    new Windows.Networking.HostName(resourceURI.Host);

string identity = await ProtectionPolicyManager.
    GetPrimaryManagedIdentityForNetworkEndpointAsync(hostName);

APIs
ProtectionPolicyManager.GetPrimaryManagedIdentityForNetworkEndpointAsync

Etapa 2: Criar um contexto de thread protegido e enviar dados para o ponto de extremidade de rede

HttpClient client = null;

if (!string.IsNullOrEmpty(m_EnterpriseId))
{
    ProtectionPolicyManager.GetForCurrentView().Identity = identity;

    using (ThreadNetworkContext threadNetworkContext =
            ProtectionPolicyManager.CreateCurrentThreadNetworkContext(identity))
    {
        client = new HttpClient();
        HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Put, resourceURI);
        message.Content = new HttpStreamContent(dataToWrite);

        HttpResponseMessage response = await client.SendRequestAsync(message);

        if (response.StatusCode == HttpStatusCode.Ok)
            return true;
        else
            return false;
    }
}
else
{
    return false;
}

APIs
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity
ProtectionPolicyManager.CreateCurrentThreadNetworkContext

Proteger os dados que seu aplicativo compartilha por meio de um contrato de compartilhamento

Se você quiser que os usuários compartilhem conteúdo do seu aplicativo, precisará implementar um contrato de compartilhamento e manipular o evento DataTransferManager.DataRequested.

No manipulador de eventos, defina o contexto de identidade corporativa no pacote de dados.

private void OnShareSourceOperation(object sender, RoutedEventArgs e)
{
    // Register the current page as a share source (or you could do this earlier in your app).
    DataTransferManager.GetForCurrentView().DataRequested += OnDataRequested;
    DataTransferManager.ShowShareUI();
}

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
    if (!string.IsNullOrEmpty(this.shareSourceContent))
    {
        var protectionPolicyManager = ProtectionPolicyManager.GetForCurrentView();
        DataPackage requestData = args.Request.Data;
        requestData.Properties.Title = this.shareSourceTitle;
        requestData.Properties.EnterpriseId = protectionPolicyManager.Identity;
        requestData.SetText(this.shareSourceContent);
    }
}

APIs
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity

Proteger arquivos que você copia para outro local

private async void CopyProtectionFromOneFileToAnother
    (StorageFile sourceStorageFile, StorageFile targetStorageFile)
{
    bool copyResult = await
        FileProtectionManager.CopyProtectionAsync(sourceStorageFile, targetStorageFile);

    if (!copyResult)
    {
        // Copying failed. To diagnose, you could check the file's status.
        // (call FileProtectionManager.GetProtectionInfoAsync and
        // check FileProtectionInfo.Status).
    }
}

APIs
FileProtectionManager.CopyProtectionAsync

Proteja os dados corporativos quando a tela do dispositivo estiver bloqueada

Remova todos os dados confidenciais da memória quando o dispositivo estiver bloqueado. Quando o usuário desbloqueia o dispositivo, seu aplicativo pode adicionar esses dados com segurança.

Manipule o evento ProtectionPolicyManager.ProtectedAccessSuspending para que seu aplicativo saiba quando a tela está bloqueada. Esse evento será gerado somente se o administrador configurar uma proteção de dados segura na política de bloqueio. O Windows remove temporariamente as chaves de proteção de dados provisionadas no dispositivo. O Windows remove essas chaves para garantir que não haja acesso não autorizado a dados criptografados enquanto o dispositivo estiver bloqueado e possivelmente não estiver em posse de seu proprietário.

Manipule o evento ProtectionPolicyManager.ProtectedAccessResumed para que seu aplicativo saiba quando a tela está desbloqueada. Esse evento é gerado independentemente de o administrador configurar uma proteção de dados segura na política de bloqueio.

Remova dados confidenciais da memória quando a tela estiver bloqueada

Proteja dados confidenciais e feche todos os fluxos de arquivos que seu aplicativo abriu em arquivos protegidos para ajudar a garantir que o sistema não armazene em cache nenhum dado confidencial na memória.

Este exemplo salva o conteúdo de um bloco de texto em um buffer criptografado e remove o conteúdo desse bloco de texto.

private async void ProtectionPolicyManager_ProtectedAccessSuspending(object sender, ProtectedAccessSuspendingEventArgs e)
{
    Deferral deferral = e.GetDeferral();

    if (ProtectionPolicyManager.GetForCurrentView().Identity != String.Empty)
    {
        IBuffer documentBodyBuffer = CryptographicBuffer.ConvertStringToBinary
           (documentTextBlock.Text, BinaryStringEncoding.Utf8);

        BufferProtectUnprotectResult result = await DataProtectionManager.ProtectAsync
            (documentBodyBuffer, ProtectionPolicyManager.GetForCurrentView().Identity);

        if (result.ProtectionInfo.Status == DataProtectionStatus.Protected)
        {
            this.protectedDocumentBuffer = result.Buffer;
            documentTextBlock.Text = null;
        }
    }

    // Close any open streams that you are actively working with
    // to make sure that we have no unprotected content in memory.

    // Optionally, code goes here to use e.Deadline to determine whether we have more
    // than 15 seconds left before the suspension deadline. If we do then process any
    // messages queued up for sending while we are still able to access them.

    deferral.Complete();
}

APIs
ProtectionPolicyManager.ProtectedAccessSuspending
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity
DataProtectionManager.ProtectAsync
BufferProtectUnprotectResult.buffer
ProtectedAccessSuspendingEventArgs.GetDeferral
Diferimento.Concluído

Adicionar de volta dados confidenciais quando o dispositivo for desbloqueado

ProtectionPolicyManager.ProtectedAccessResumed é gerado quando o dispositivo é desbloqueado e as chaves estão disponíveis no dispositivo novamente.

ProtectedAccessResumedEventArgs.Identities será uma coleção vazia se o administrador não tiver configurado uma proteção de dados segura na política de bloqueio.

Este exemplo faz o inverso do exemplo anterior. Ele descriptografa o buffer, adiciona informações desse buffer de volta à caixa de texto e, em seguida, descarta o buffer.

private async void ProtectionPolicyManager_ProtectedAccessResumed(object sender, ProtectedAccessResumedEventArgs e)
{
    if (ProtectionPolicyManager.GetForCurrentView().Identity != String.Empty)
    {
        BufferProtectUnprotectResult result = await DataProtectionManager.UnprotectAsync
            (this.protectedDocumentBuffer);

        if (result.ProtectionInfo.Status == DataProtectionStatus.Unprotected)
        {
            // Restore the unprotected version.
            documentTextBlock.Text = CryptographicBuffer.ConvertBinaryToString
                (BinaryStringEncoding.Utf8, result.Buffer);
            this.protectedDocumentBuffer = null;
        }
    }

}

APIs
ProtectionPolicyManager.ProtectedAccessResumed
ProtectionPolicyManager.GetForCurrentView
ProtectionPolicyManager.Identity
DataProtectionManager.UnprotectAsync
BufferProtectUnprotectResult.Status

Lidar com dados corporativos quando o conteúdo protegido for revogado

Se você quiser que seu aplicativo seja notificado quando o registro do dispositivo for cancelado do MDM ou quando o administrador da política revogar explicitamente o acesso aos dados corporativos, manipule o evento ProtectionPolicyManager_ProtectedContentRevoked.

Este exemplo determina se os dados em uma caixa de correio corporativa para um aplicativo de email foram revogados.

private string mailIdentity = "contoso.com";

void MailAppSetup()
{
    ProtectionPolicyManager.ProtectedContentRevoked += ProtectionPolicyManager_ProtectedContentRevoked;
    // Code goes here to set up mailbox for 'mailIdentity'.
}

private void ProtectionPolicyManager_ProtectedContentRevoked(object sender, ProtectedContentRevokedEventArgs e)
{
    if (!new System.Collections.Generic.List<string>(e.Identities).Contains
        (this.mailIdentity))
    {
        // This event is not for our identity.
        return;
    }

    // Code goes here to delete any metadata associated with 'mailIdentity'.
}

APIs
ProtectionPolicyManager_ProtectedContentRevoked

Exemplo de WIP (Proteção de Informações do Windows)