| File: DataProtectionAdvancedExtensions.cs | Web Access |
| Project: src\aspnetcore\src\DataProtection\Extensions\src\Microsoft.AspNetCore.DataProtection.Extensions.csproj (Microsoft.AspNetCore.DataProtection.Extensions) |
// 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.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Shared; namespace Microsoft.AspNetCore.DataProtection; /// <summary> /// Helpful extension methods for data protection APIs. /// </summary> public static class DataProtectionAdvancedExtensions { /// <summary> /// Cryptographically protects a piece of plaintext data, expiring the data after /// the specified amount of time has elapsed. /// </summary> /// <param name="protector">The protector to use.</param> /// <param name="plaintext">The plaintext data to protect.</param> /// <param name="lifetime">The amount of time after which the payload should no longer be unprotectable.</param> /// <returns>The protected form of the plaintext data.</returns> public static byte[] Protect(this ITimeLimitedDataProtector protector, byte[] plaintext, TimeSpan lifetime) { ArgumentNullThrowHelper.ThrowIfNull(protector); ArgumentNullThrowHelper.ThrowIfNull(plaintext); return protector.Protect(plaintext, DateTimeOffset.UtcNow + lifetime); } /// <summary> /// Cryptographically protects a piece of plaintext data, expiring the data at /// the chosen time. /// </summary> /// <param name="protector">The protector to use.</param> /// <param name="plaintext">The plaintext data to protect.</param> /// <param name="expiration">The time when this payload should expire.</param> /// <returns>The protected form of the plaintext data.</returns> public static string Protect(this ITimeLimitedDataProtector protector, string plaintext, DateTimeOffset expiration) { ArgumentNullThrowHelper.ThrowIfNull(protector); ArgumentNullThrowHelper.ThrowIfNull(plaintext); var wrappingProtector = new TimeLimitedWrappingProtector(protector) { Expiration = expiration }; return wrappingProtector.Protect(plaintext); } /// <summary> /// Cryptographically protects a piece of plaintext data, expiring the data after /// the specified amount of time has elapsed. /// </summary> /// <param name="protector">The protector to use.</param> /// <param name="plaintext">The plaintext data to protect.</param> /// <param name="lifetime">The amount of time after which the payload should no longer be unprotectable.</param> /// <returns>The protected form of the plaintext data.</returns> public static string Protect(this ITimeLimitedDataProtector protector, string plaintext, TimeSpan lifetime) { ArgumentNullThrowHelper.ThrowIfNull(protector); ArgumentNullThrowHelper.ThrowIfNull(plaintext); return Protect(protector, plaintext, DateTimeOffset.Now + lifetime); } /// <summary> /// Converts an <see cref="IDataProtector"/> into an <see cref="ITimeLimitedDataProtector"/> /// so that payloads can be protected with a finite lifetime. /// </summary> /// <param name="protector">The <see cref="IDataProtector"/> to convert to a time-limited protector.</param> /// <returns>An <see cref="ITimeLimitedDataProtector"/>.</returns> public static ITimeLimitedDataProtector ToTimeLimitedDataProtector(this IDataProtector protector) { ArgumentNullThrowHelper.ThrowIfNull(protector); return (protector as ITimeLimitedDataProtector) ?? new TimeLimitedDataProtector(protector); } /// <summary> /// Cryptographically unprotects a piece of protected data. /// </summary> /// <param name="protector">The protector to use.</param> /// <param name="protectedData">The protected data to unprotect.</param> /// <param name="expiration">An 'out' parameter which upon a successful unprotect /// operation receives the expiration date of the payload.</param> /// <returns>The plaintext form of the protected data.</returns> /// <exception cref="System.Security.Cryptography.CryptographicException"> /// Thrown if <paramref name="protectedData"/> is invalid, malformed, or expired. /// </exception> public static string Unprotect(this ITimeLimitedDataProtector protector, string protectedData, out DateTimeOffset expiration) { ArgumentNullThrowHelper.ThrowIfNull(protector); ArgumentNullThrowHelper.ThrowIfNull(protectedData); var wrappingProtector = new TimeLimitedWrappingProtector(protector); string retVal = wrappingProtector.Unprotect(protectedData); expiration = wrappingProtector.Expiration; return retVal; } private sealed class TimeLimitedWrappingProtector : IDataProtector { public DateTimeOffset Expiration; private readonly ITimeLimitedDataProtector _innerProtector; public TimeLimitedWrappingProtector(ITimeLimitedDataProtector innerProtector) { _innerProtector = innerProtector; } public IDataProtector CreateProtector(string purpose) { ArgumentNullThrowHelper.ThrowIfNull(purpose); throw new NotImplementedException(); } public byte[] Protect(byte[] plaintext) { ArgumentNullThrowHelper.ThrowIfNull(plaintext); return _innerProtector.Protect(plaintext, Expiration); } public byte[] Unprotect(byte[] protectedData) { ArgumentNullThrowHelper.ThrowIfNull(protectedData); return _innerProtector.Unprotect(protectedData, out Expiration); } } }