<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="8.0.0-rc.1.23419.4" />

ProtectedData

public static class ProtectedData
Provides methods for encrypting and decrypting data. This class cannot be inherited.
using Internal.Cryptography; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Security.Cryptography { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class ProtectedData { private static readonly byte[] s_nonEmpty = new byte[1]; public static byte[] Protect(byte[] userData, [System.Runtime.CompilerServices.Nullable(2)] byte[] optionalEntropy, DataProtectionScope scope) { CheckPlatformSupport(); if (userData == null) throw new ArgumentNullException("userData"); return ProtectOrUnprotect(userData, optionalEntropy, scope, true); } public static byte[] Unprotect(byte[] encryptedData, [System.Runtime.CompilerServices.Nullable(2)] byte[] optionalEntropy, DataProtectionScope scope) { CheckPlatformSupport(); if (encryptedData == null) throw new ArgumentNullException("encryptedData"); return ProtectOrUnprotect(encryptedData, optionalEntropy, scope, false); } private unsafe static byte[] ProtectOrUnprotect(byte[] inputData, byte[] optionalEntropy, DataProtectionScope scope, bool protect) { byte[] array = (inputData.Length == 0) ? s_nonEmpty : inputData; fixed (byte* value = array) { fixed (byte* value2 = optionalEntropy) { global::Interop.Crypt32.DATA_BLOB pDataIn = new global::Interop.Crypt32.DATA_BLOB((IntPtr)(void*)value, (uint)inputData.Length); global::Interop.Crypt32.DATA_BLOB pOptionalEntropy = default(global::Interop.Crypt32.DATA_BLOB); if (optionalEntropy != null) pOptionalEntropy = new global::Interop.Crypt32.DATA_BLOB((IntPtr)(void*)value2, (uint)optionalEntropy.Length); global::Interop.Crypt32.CryptProtectDataFlags cryptProtectDataFlags = global::Interop.Crypt32.CryptProtectDataFlags.CRYPTPROTECT_UI_FORBIDDEN; if (scope == DataProtectionScope.LocalMachine) cryptProtectDataFlags |= global::Interop.Crypt32.CryptProtectDataFlags.CRYPTPROTECT_LOCAL_MACHINE; global::Interop.Crypt32.DATA_BLOB pDataOut = default(global::Interop.Crypt32.DATA_BLOB); try { if (!(protect ? global::Interop.Crypt32.CryptProtectData(ref pDataIn, null, ref pOptionalEntropy, IntPtr.Zero, IntPtr.Zero, cryptProtectDataFlags, out pDataOut) : global::Interop.Crypt32.CryptUnprotectData(ref pDataIn, IntPtr.Zero, ref pOptionalEntropy, IntPtr.Zero, IntPtr.Zero, cryptProtectDataFlags, out pDataOut))) { int lastWin32Error = Marshal.GetLastWin32Error(); if (protect && ErrorMayBeCausedByUnloadedProfile(lastWin32Error)) throw new CryptographicException(System.SR.Cryptography_DpApi_ProfileMayNotBeLoaded); throw lastWin32Error.ToCryptographicException(); } if (pDataOut.pbData == IntPtr.Zero) throw new OutOfMemoryException(); int cbData = (int)pDataOut.cbData; byte[] array2 = new byte[cbData]; Marshal.Copy(pDataOut.pbData, array2, 0, cbData); return array2; } finally { if (pDataOut.pbData != IntPtr.Zero) { int cbData2 = (int)pDataOut.cbData; byte* ptr = (byte*)(void*)pDataOut.pbData; for (int i = 0; i < cbData2; i++) { ptr[i] = 0; } Marshal.FreeHGlobal(pDataOut.pbData); } } } } } private static bool ErrorMayBeCausedByUnloadedProfile(int errorCode) { if (errorCode != -2147024894) return errorCode == 2; return true; } private static void CheckPlatformSupport() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) throw new PlatformNotSupportedException(); } } }