P/Invoke와 함께 CredRead
및 CredWrite
을 통해 Credential Vault를 사용할 수 있습니다. 그것은 기록되거나 가장 된 사용자에게 특정적이고 해독하기 위해 암호를 요구하지 않습니다.
다음은 내 배포 작업 중 하나입니다. 사용자 작업에서만 액세스 할 수있는 가장을위한 암호를 안전하게 검색하는 방법의 예입니다. control /name Microsoft.CredentialManager
또는 cmdkey /?
또는 CredWrite
을 통해 설정할 수 있습니다.
private Task Impersonate()
{
if (As == null)
return this;
Log.Debug("[As] {0}", As);
IntPtr token;
if (!CredRead(As, 1, 0, out token))
throw new Win32Exception();
var cred = (Credential)Marshal.PtrToStructure(token, typeof(Credential));
CredFree(token);
var name = cred.UserName.Split('\\');
var user = new { Name = name[1], Domain = name[0], Password = Marshal.PtrToStringAuto(cred.CredentialBlob) };
Log.Info("[As] {0}\\{1}", user.Domain, user.Name);
if (!LogonUser(user.Name, user.Domain, user.Password, 9, 0, out token))
throw new Win32Exception();
Context = WindowsIdentity.Impersonate(token);
if (!CloseHandle(token))
throw new Win32Exception();
return this;
}
[DllImport("advapi32", SetLastError = true)]
private static extern bool CredRead(string target, uint type, uint flags, out IntPtr credential);
[DllImport("advapi32", SetLastError = true)]
private static extern void CredFree(IntPtr buffer);
[DllImport("advapi32", SetLastError = true)]
private static extern bool LogonUser(string username, string domain, string password, int type, int provider, out IntPtr token);
[DllImport("kernel32", SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);
private struct Credential
{
#pragma warning disable 169, 649
public uint Flags;
public uint Type;
public string TargetName;
public string Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public uint CredentialBlobSize;
public IntPtr CredentialBlob;
public uint Persist;
public uint AttributeCount;
public IntPtr Attributes;
public string TargetAlias;
public string UserName;
#pragma warning restore 169, 649
}
의 암호를 해독하는 데 도움이됩니다. 미리 정의 된 고정 키를 사용하는 것은 일반적으로 처음부터 일반 텍스트/암호화되지 않은 데이터를 저장하는 것과 동일합니다. –