Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este guia mostra aos desenvolvedores como descriptografar instantâneos exportados Recall para uso em aplicativos. Você aprenderá o processo de descriptografia completo com exemplos de código funcional para implementação imediata.
A exportação Recall de instantâneos só tem suporte em dispositivos na EEE (Área Econômica Europeia). A exportação de Recall instantâneos é um processo iniciado pelo usuário e é para cada usuário. Instantâneos exportados são criptografados.
Saiba mais sobre como exportar Recall instantâneos ou ver a Recall visão geral de como esse recurso com suporte de IA funciona.
Pré-requisitos
A opção de exportar Recall instantâneos só está disponível em dispositivos Copilot+ PC na Área Econômica Europeia (EEA) com a versão mais recente do Programa Windows Insider.
Antes de começar, você precisará:
- Instantâneos exportados: o usuário deve primeiro exportar Recall instantâneos e fornecer o caminho da pasta onde eles são salvos.
- Código de exportação: o código de exportação de 32 caracteres Recall fornecido durante a exportação de instantâneo.
- Pasta de saída: um caminho de pasta de destino em que os arquivos .jpg e .json descriptografados associados aos instantâneos exportados serão salvos.
Como descriptografar instantâneos exportados Recall
Comece com o código de exemplo para descriptografar instantâneos exportados Recall no repositório GitHub RecallSnapshotsExport. Siga o processo passo a passo abaixo para entender como a descriptografia funciona.
Chave de Exportação de Computação
O usuário precisará fornecer o local (caminho da pasta) onde os instantâneos exportados Recall foram salvos, além do código de exportação Recall que foi solicitado para que o usuário salvasse durante a configuração inicial Recall. O Recall código de exportação é semelhante a: 0a0a-0a0a-1111-bbbb-2222-3c3c-3c3c-3c3c
Primeiro, remova o traço – para resultar em uma cadeia de caracteres de 32 caracteres: 0a0a0a0a1111bbbb22223c3c3c3c3c3c
std::wstring UnexpandExportCode(std::wstring code)
{
if (code.size() > 32)
{
code.erase(std::remove(code.begin(), code.end(), ' '), code.end()); // Remove spaces
code.erase(std::remove(code.begin(), code.end(), '-'), code.end()); // Remove hyphens
}
if (code.size() != 32)
{
std::wcout << L"The export code has incorrect number of characters."<< std::endl;
}
return code;
}
Em seguida, crie uma matriz que contenha o valor em byte para cada par de dígitos hexadecimais.
std::vector<uint8_t> HexStringToBytes(const std::wstring& hexString)
{
std::vector<uint8_t> bytes;
if (hexString.length() % 2 != 0)
{
throw std::invalid_argument("Hex string must have an even length");
}
for (size_t i = 0; i < hexString.length(); i += 2)
{
std::wstring byteString = hexString.substr(i, 2);
uint8_t byte = static_cast<uint8_t>(std::stoi(byteString, nullptr, 16));
bytes.push_back(byte);
}
return bytes;
}
Em seguida, pegue essa matriz e compute o hash SHA256, que resulta em um valor de 32 bytes, que é a chave de exportação. Agora, qualquer número de snapshots pode ser descriptografado usando a chave de exportação resultante.
std::vector<uint8_t> exportKeyBytes(c_keySizeInBytes);
THROW_IF_NTSTATUS_FAILED(BCryptHash(
BCRYPT_SHA256_ALG_HANDLE,
nullptr,
0,
exportCodeBytes.data(),
static_cast<ULONG>(exportCodeBytes.size()),
exportKeyBytes.data(),
c_keySizeInBytes));
Descriptografar os instantâneos criptografados
O layout de um snapshot (no formato little-endian): | uint32_t version | uint32_t encryptedKeySize | uint32_t encryptedContentSize | uint32_t contentType | uint8_t[KeySIze] encryptedContentKey | uint8_t[ContentSize] encryptedContent |
Primeiro, leia os quatro valores uint32_t.
EncryptedSnapshotHeader header{};
reader.ByteOrder(winrt::ByteOrder::LittleEndian);
header.Version = reader.ReadUInt32();
header.KeySize = reader.ReadUInt32();
header.ContentSize = reader.ReadUInt32();
header.ContentType = reader.ReadUInt32();
Em seguida, verifique se a versão tem o valor 2.
if (header.Version != 2)
{
throw std::runtime_error("Insufficient data header version.");
}
Em seguida, leia o conteúdo da chave criptografada.
std::vector<uint8_t> keybytes(header.KeySize);
reader.ReadBytes(keybytes);
Descriptografar o conteúdoChaveCriptografado
wil::unique_bcrypt_key DecryptExportKey(BCRYPT_KEY_HANDLE key, std::span<uint8_t const> encryptedKey)
{
THROW_HR_IF(E_INVALIDARG, encryptedKey.size() != c_totalSizeInBytes);
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO AuthInfo{};
BCRYPT_INIT_AUTH_MODE_INFO(AuthInfo);
AuthInfo.pbNonce = const_cast<uint8_t*>(encryptedKey.data());
AuthInfo.cbNonce = c_nonceSizeInBytes;
AuthInfo.pbTag = const_cast<uint8_t*>(encryptedKey.data() + c_nonceSizeInBytes + c_childKeySizeInBytes);
AuthInfo.cbTag = c_tagSizeInBytes;
uint8_t decryptedKey[c_childKeySizeInBytes] = { 0 };
ULONG decryptedByteCount{};
THROW_IF_FAILED(HResultFromBCryptStatus(BCryptDecrypt(
key,
const_cast<uint8_t*>(encryptedKey.data() + c_nonceSizeInBytes),
c_childKeySizeInBytes,
&AuthInfo,
nullptr,
0,
decryptedKey,
sizeof(decryptedKey),
&decryptedByteCount,
0)));
wil::unique_bcrypt_key childKey;
THROW_IF_NTSTATUS_FAILED(
BCryptGenerateSymmetricKey(BCRYPT_AES_GCM_ALG_HANDLE, &childKey, nullptr, 0, decryptedKey, c_childKeySizeInBytes, 0));
return childKey;
}
usando a `exportKey`
wil::unique_bcrypt_key exportKey;
THROW_IF_NTSTATUS_FAILED(BCryptGenerateSymmetricKey(
BCRYPT_AES_GCM_ALG_HANDLE, &exportKey, nullptr, 0, exportKeyBytes.data(), static_cast<ULONG>(exportKeyBytes.size()), 0));
Para obter a contentKey (o algoritmo de criptografia é AES_GCM)
wil::unique_bcrypt_key contentKey = DecryptExportKey(exportKey.get(), keybytes);
Leia o conteúdoCriptografado
std::vector<uint8_t> contentbytes(header.ContentSize);
reader.ReadBytes(contentbytes);
Descriptografar o conteúdoCriptografado
std::vector<uint8_t> DecryptPackedData(BCRYPT_KEY_HANDLE key, std::span<uint8_t const> payload)
{
THROW_HR_IF(E_INVALIDARG, payload.size() < c_tagSizeInBytes);
const auto dataSize = payload.size() - c_tagSizeInBytes;
const auto data = payload.data();
uint8_t zeroNonce[c_nonceSizeInBytes] = { 0 };
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo{};
BCRYPT_INIT_AUTH_MODE_INFO(authInfo);
authInfo.pbNonce = zeroNonce;
authInfo.cbNonce = c_nonceSizeInBytes;
authInfo.pbTag = const_cast<uint8_t*>(payload.data() + dataSize);
authInfo.cbTag = c_tagSizeInBytes;
std::vector<uint8_t> decryptedContent(dataSize);
ULONG decryptedSize = 0;
const auto result = BCryptDecrypt(
key, const_cast<uint8_t*>(data), static_cast<ULONG>(dataSize), &authInfo, nullptr, 0, decryptedContent.data(), static_cast<ULONG>(dataSize), &decryptedSize, 0);
decryptedContent.resize(decryptedSize);
THROW_IF_FAILED(HResultFromBCryptStatus(result));
return decryptedContent;
}
com o contentKey (o algoritmo de criptografia é AES_GCM)
std::vector<uint8_t> decryptedContent = DecryptPackedData(contentKey.get(), contentbytes);
Exporte o conteúdo descriptografado do instantâneo Recall como uma imagem .jpg com metadados correspondentes em .json para o caminho da pasta designada.
void WriteSnapshotToOutputFolder(winrt::StorageFolder const& outputFolder, winrt::hstring const& fileName, winrt::IRandomAccessStream const& decryptedStream)
A saída esperada incluirá:
- Instantâneos descriptografados salvos como arquivos .jpg.
- Metadados correspondentes salvos como arquivos .json.
Ambos os tipos de arquivo compartilharão o mesmo nome de arquivo e serão encontrados na pasta de saída especificada.
Saiba mais sobre Recall
- Saiba mais sobre o Windows Recall.
- Exportar Recall instantâneos com um código de exportação
- Gerenciar Recall: permitir a exportação de informações de Recall e dados de instantâneos: diretrizes do administrador de TI sobre como gerenciar configurações de Recall para usuários em sua empresa, incluindo a capacidade de exportar dados de instantâneos Recall.
- Política do CSP (Provedor de Serviços de Configuração) para IA do Windows: Permitir Recall Exportação: Diretrizes para os administradores de TI estabelecerem as configurações de política que determinam se o recurso opcional Recall está disponível para os usuários finais habilitarem em seu dispositivo, incluindo a política para habilitar a exportação de dados de instantâneo.
Windows developer