| File: XmlEncryption\DpapiXmlEncryptor.cs | Web Access |
| Project: src\aspnetcore\src\DataProtection\DataProtection\src\Microsoft.AspNetCore.DataProtection.csproj (Microsoft.AspNetCore.DataProtection) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Runtime.Versioning; using System.Security.Principal; using System.Xml.Linq; using Microsoft.AspNetCore.Cryptography; using Microsoft.AspNetCore.DataProtection.Cng; using Microsoft.AspNetCore.Shared; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.DataProtection.XmlEncryption; /// <summary> /// An <see cref="IXmlEncryptor"/> that encrypts XML by using Windows DPAPI. /// </summary> /// <remarks> /// This API is only supported on Windows platforms. /// </remarks> [SupportedOSPlatform("windows")] public sealed class DpapiXmlEncryptor : IXmlEncryptor { private readonly ILogger _logger; private readonly bool _protectToLocalMachine; /// <summary> /// Creates a <see cref="DpapiXmlEncryptor"/> given a protection scope and an <see cref="IServiceProvider"/>. /// </summary> /// <param name="protectToLocalMachine">'true' if the data should be decipherable by anybody on the local machine, /// 'false' if the data should only be decipherable by the current Windows user account.</param> /// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param> public DpapiXmlEncryptor(bool protectToLocalMachine, ILoggerFactory loggerFactory) { CryptoUtil.AssertPlatformIsWindows(); _protectToLocalMachine = protectToLocalMachine; _logger = loggerFactory.CreateLogger<DpapiXmlEncryptor>(); } /// <summary> /// Encrypts the specified <see cref="XElement"/>. /// </summary> /// <param name="plaintextElement">The plaintext to encrypt.</param> /// <returns> /// An <see cref="EncryptedXmlInfo"/> that contains the encrypted value of /// <paramref name="plaintextElement"/> along with information about how to /// decrypt it. /// </returns> public EncryptedXmlInfo Encrypt(XElement plaintextElement) { ArgumentNullThrowHelper.ThrowIfNull(plaintextElement); if (_protectToLocalMachine) { _logger.EncryptingToWindowsDPAPIForLocalMachineAccount(); } else { _logger.EncryptingToWindowsDPAPIForCurrentUserAccount(WindowsIdentity.GetCurrent().Name); } // Convert the XML element to a binary secret so that it can be run through DPAPI byte[] dpapiEncryptedData; try { using (var plaintextElementAsSecret = plaintextElement.ToSecret()) { dpapiEncryptedData = DpapiSecretSerializerHelper.ProtectWithDpapi(plaintextElementAsSecret, protectToLocalMachine: _protectToLocalMachine); } } catch (Exception ex) { _logger.ErrorOccurredWhileEncryptingToWindowsDPAPI(ex); throw; } // <encryptedKey> // <!-- This key is encrypted with {provider}. --> // <value>{base64}</value> // </encryptedKey> var element = new XElement("encryptedKey", new XComment(" This key is encrypted with Windows DPAPI. "), new XElement("value", Convert.ToBase64String(dpapiEncryptedData))); return new EncryptedXmlInfo(element, typeof(DpapiXmlDecryptor)); } }