public static void Unprotect(byte[] encryptedData, MemoryProtectionScope scope) { if (encryptedData == null) { throw new ArgumentNullException("encryptedData"); } if (Environment.OSVersion.Platform == PlatformID.Win32Windows) { throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); } VerifyScope(scope); // The RtlEncryptMemory and RtlDecryptMemory functions are available on WinXP and publicly published // in the ntsecapi.h header file as of Windows Server 2003. // The Rtl functions accept data in 8 byte increments, but we don't want applications to be able to make use of this, // or else they're liable to break when the user upgrades. if ((encryptedData.Length == 0) || (encryptedData.Length % CAPI.CRYPTPROTECTMEMORY_BLOCK_SIZE != 0)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_InvalidMemoryLength")); } uint dwFlags = (uint)scope; try { // RtlDecryptMemory return an NTSTATUS int status = CAPI.SystemFunction041(encryptedData, (uint)encryptedData.Length, dwFlags); if (status < 0) // non-negative numbers indicate success { throw new CryptographicException(CAPI.CAPISafe.LsaNtStatusToWinError(status)); } } catch (EntryPointNotFoundException) { throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); } }