如何解密本地存储的密钥尽可能安全

时间:2014-06-10 09:28:04

标签: c# .net encryption

我有一个我需要在应用程序中使用的密钥。该密钥必须以持久的方式存储在设备上。我需要恢复此密钥而不使用外部输入,如用户密码。任何需要网络/服务器连接的身份验证(除了使用Active Directory验证初始系统登录之外)在此处都不可用。

现在,为了自己解密任何加密数据,我需要一个解密的私钥,这个私钥必须再次存储在某个地方,而且我不确定这里的最佳做法。

在Windows 7中使用.NET存储和解密所述密钥的最安全方法是什么?

2 个答案:

答案 0 :(得分:0)

您可以通过CredRead使用凭据保险库,使用P / Invoke使用CredWrite。它特定于被记录或模拟的用户,并且不需要密码来解密。

这是我的一个部署任务的示例,该示例说明了如何安全地检索只能由用户任务访问的模拟密码。可以通过control /name Microsoft.CredentialManagercmdkey /?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
}

答案 1 :(得分:0)

DPAPI应该可以帮助您透明地加密和解密密钥