Skip to content

Instantly share code, notes, and snippets.

@rusanu
Created January 23, 2018 07:09
Show Gist options
  • Save rusanu/e597959490b61bdf94ae0a73602f2340 to your computer and use it in GitHub Desktop.
Save rusanu/e597959490b61bdf94ae0a73602f2340 to your computer and use it in GitHub Desktop.
NCrypt module
$apiDefinition = @'
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
public class NCryptApi
{
//public const NCRYPT_MACHINE_KEY_FLAG = ;
//public const NCRYPT_NAMED_DESCRIPTOR_FLAG = ;
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh706800(v=vs.85).aspx
[DllImport("ncrypt.dll", CharSet = CharSet.Unicode)]
internal extern static int NCryptCreateProtectionDescriptor(
[In] string pwszDescriptorString,
[In] uint dwFlags,
[Out] out IntPtr phDescriptor);
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh706802(v=vs.85).aspx
[DllImport("ncrypt.dll")]
internal extern static int NCryptProtectSecret(
[In] IntPtr hDescriptor,
[In] uint dwFlags,
[In] byte[] pbData,
[In] uint cbData,
[In] IntPtr pMemPara,
[In] IntPtr hWnd,
[Out] out IntPtr ppbProtectedBlob,
[Out] out uint pcbProtectedBlob);
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh706811(v=vs.85).aspx
[DllImport("ncrypt.dll")]
internal extern static int NCryptUnprotectSecret(
[In] IntPtr phDescriptor,
[In] uint dwFlags,
[In] byte[] pbProtectedBlob,
[In] uint cbProtectedBlob,
[In] IntPtr pMemPara,
[In] IntPtr hWnd,
[Out] out IntPtr ppbData,
[Out] out uint pcbData);
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh706799(v=vs.85).aspx
[DllImport("ncrypt.dll")]
internal extern static int NCryptCloseProtectionDescriptor(
[In] IntPtr phDescriptor);
public static IntPtr CreateProtectionDescriptor(string descriptor)
{
IntPtr sh;
int err = NCryptCreateProtectionDescriptor(descriptor, 0, out sh);
if (0 != err)
{
throw new Win32Exception(err);
}
return sh;
}
public static byte[] ProtectSecret(IntPtr hDescriptor, byte[] secret)
{
byte[] bytesOut;
IntPtr ptrOut;
uint cbOut;
int err = NCryptProtectSecret(hDescriptor, 0, secret, (uint) secret.Length, IntPtr.Zero, IntPtr.Zero, out ptrOut, out cbOut);
if (0 != err)
{
throw new Win32Exception(err);
}
bytesOut = new byte[cbOut];
Marshal.Copy(ptrOut, bytesOut, 0, (int) cbOut);
Marshal.FreeHGlobal(ptrOut);
return bytesOut;
}
public static byte[] UnprotectSecret(IntPtr hDescriptor, byte[] cipher)
{
byte[] bytesOut;
IntPtr ptrOut;
uint cbOut;
int err = NCryptUnprotectSecret(hDescriptor, 0, cipher, (uint) cipher.Length, IntPtr.Zero, IntPtr.Zero, out ptrOut, out cbOut);
if (0 != err)
{
throw new Win32Exception(err);
}
bytesOut = new byte[cbOut];
Marshal.Copy(ptrOut, bytesOut, 0, (int) cbOut);
Marshal.FreeHGlobal(ptrOut);
return bytesOut;
}
public static void CloseHandle(IntPtr hDescriptor)
{
int err = NCryptCloseProtectionDescriptor(hDescriptor);
if (0 != err)
{
throw new Win32Exception(err);
}
}
}
'@
$null = Add-Type $apiDefinition -PassThru
function New-NCryptDescriptorHandle {
param(
[Parameter(Mandatory=$true, Position=0)]
[string] $descriptor
)
[NCryptApi]::CreateProtectionDescriptor($descriptor)
}
function Remove-NCryptDescriptorHandle {
param(
[Parameter(Mandatory=$true, Position=0)]
[IntPtr] $descriptorHandle
)
[NCryptAPI]::CloseHandle($descriptorHandle)
}
function Protect-NCryptSecret {
param(
[Parameter(Mandatory=$true, Position=0)]
[IntPtr] $descriptorHandle,
[Parameter(Mandatory=$true, Position=1)]
[byte[]] $secret
)
[NCryptAPI]::ProtectSecret($descriptorHandle, $secret)
}
function Unprotect-NCryptSecret {
param(
[Parameter(Mandatory=$true, Position=0)]
[IntPtr] $descriptorHandle,
[Parameter(Mandatory=$true, Position=1)]
[byte[]] $cipher
)
[NCryptAPI]::UnprotectSecret($descriptorHandle, $cipher)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment