plaintext_string winrt_encryption::decrypt() const { // To fully guarantee asynchrony would require significant impact on existing code. This code path // is never run on a user's thread and is only done once when setting up a connection. auto encrypted = m_buffer.get(); auto provider = ref new Windows::Security::Cryptography::DataProtection::DataProtectionProvider(); auto plaintext = pplx::create_task(provider->UnprotectAsync(encrypted)).get(); // Get access to raw bytes in plain text buffer. Microsoft::WRL::ComPtr<IInspectable> bufferInspectable(reinterpret_cast<IInspectable *>(plaintext)); Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess; bufferInspectable.As(&bufferByteAccess); byte * rawPlaintext; const auto &result = bufferByteAccess->Buffer(&rawPlaintext); if (result != S_OK) { throw ::utility::details::create_system_error(result); } // Construct string and zero out memory from plain text buffer. auto data = plaintext_string(new std::wstring( reinterpret_cast<const std::wstring::value_type *>(rawPlaintext), plaintext->Length / 2)); SecureZeroMemory(rawPlaintext, plaintext->Length); return std::move(data); }