public void Encrypt_CurrentUserOrLocalMachine_Decrypt_RoundTrips(bool protectToLocalMachine) { // Arrange var originalXml = XElement.Parse(@"<mySecret value='265ee4ea-ade2-43b1-b706-09b259e58b6b' />"); var encryptor = new DpapiXmlEncryptor(protectToLocalMachine, NullLoggerFactory.Instance); var decryptor = new DpapiXmlDecryptor(); // Act & assert - run through encryptor and make sure we get back an obfuscated element var encryptedXmlInfo = encryptor.Encrypt(originalXml); Assert.Equal(typeof(DpapiXmlDecryptor), encryptedXmlInfo.DecryptorType); Assert.DoesNotContain("265ee4ea-ade2-43b1-b706-09b259e58b6b", encryptedXmlInfo.EncryptedElement.ToString(), StringComparison.OrdinalIgnoreCase); // Act & assert - run through decryptor and make sure we get back the original value var roundTrippedElement = decryptor.Decrypt(encryptedXmlInfo.EncryptedElement); XmlAssert.Equal(originalXml, roundTrippedElement); }
internal KeyValuePair <IXmlRepository, IXmlEncryptor> GetFallbackKeyRepositoryEncryptorPair() { IXmlRepository repository = null; IXmlEncryptor encryptor = null; // If we're running in Azure Web Sites, the key repository goes in the %HOME% directory. var azureWebSitesKeysFolder = _keyStorageDirectories.GetKeyStorageDirectoryForAzureWebSites(); if (azureWebSitesKeysFolder != null) { _logger.UsingAzureAsKeyRepository(azureWebSitesKeysFolder.FullName); // Cloud DPAPI isn't yet available, so we don't encrypt keys at rest. // This isn't all that different than what Azure Web Sites does today, and we can always add this later. repository = new FileSystemXmlRepository(azureWebSitesKeysFolder, _loggerFactory); } else { // If the user profile is available, store keys in the user profile directory. var localAppDataKeysFolder = _keyStorageDirectories.GetKeyStorageDirectory(); if (localAppDataKeysFolder != null) { if (OSVersionUtil.IsWindows()) { Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); // Hint for the platform compatibility analyzer. // If the user profile is available, we can protect using DPAPI. // Probe to see if protecting to local user is available, and use it as the default if so. encryptor = new DpapiXmlEncryptor( protectToLocalMachine: !DpapiSecretSerializerHelper.CanProtectToCurrentUserAccount(), loggerFactory: _loggerFactory); } repository = new FileSystemXmlRepository(localAppDataKeysFolder, _loggerFactory); if (encryptor != null) { _logger.UsingProfileAsKeyRepositoryWithDPAPI(localAppDataKeysFolder.FullName); } else { _logger.UsingProfileAsKeyRepository(localAppDataKeysFolder.FullName); } } else { // Use profile isn't available - can we use the HKLM registry? RegistryKey regKeyStorageKey = null; if (OSVersionUtil.IsWindows()) { Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); // Hint for the platform compatibility analyzer. regKeyStorageKey = RegistryXmlRepository.DefaultRegistryKey; } if (regKeyStorageKey != null) { Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); // Hint for the platform compatibility analyzer. regKeyStorageKey = RegistryXmlRepository.DefaultRegistryKey; // If the user profile isn't available, we can protect using DPAPI (to machine). encryptor = new DpapiXmlEncryptor(protectToLocalMachine: true, loggerFactory: _loggerFactory); repository = new RegistryXmlRepository(regKeyStorageKey, _loggerFactory); _logger.UsingRegistryAsKeyRepositoryWithDPAPI(regKeyStorageKey.Name); } else { // Final fallback - use an ephemeral repository since we don't know where else to go. // This can only be used for development scenarios. repository = new EphemeralXmlRepository(_loggerFactory); _logger.UsingEphemeralKeyRepository(); } } } return(new KeyValuePair <IXmlRepository, IXmlEncryptor>(repository, encryptor)); }